Вот мой код:
const koa = require('koa');
const app = new koa();
const https = require('https')
let email = "[email protected]"
let password = "mysecret"
var options = {
host: 'myhost',
port: 443,
path: '/api/login?email=' + email + '&password=' + password,
method: 'POST'
};
async function https_req(options, callback) {
https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
callback(chunk)
})
}).end();
}
app.use(async (ctx, next) => {
let res = await https_req(options, (result) => {
console.log("final result: ",result)
ctx.body = result
})
})
app.listen(3000)
В этом коде он дает правильный результат в консоли, но на веб-странице он отображается только Not Found
Я пробовал это с экспрессом, и он работал отлично, но потом я хотел дать шанс Коа. Он работает правильно, если я просто ctx.body = 'some data'
без вызова какой-либо функции. Я думаю, что коа не ждет, даже если я напишу.
Я также попробовал async ждать внутри функции обратного вызова:
await https_req(options, async (result) => {
console.log("final result: ",result)
ctx.body = await result
})
Но он всегда дает "Не найдено".
Я также хочу знать, почему это происходит. И что я должен сделать, чтобы он работал.
Таким образом, это пример смешения кода на основе обратного вызова и кода на основе обещаний, что делает вещи немного сложными. Что происходит, так это: https_req
возвращает обещание, но только потому, что https_req
функции объявили async
return обещает. То, что он не делает, - это resolve
когда доступен результат запроса HTTPS. await
ING его, следовательно, не делать то, что вы думаете, что будет! Выполнение немедленно продолжается, и поскольку больше нет утверждений, и орган ответа никогда не устанавливается, результатом будет 404.
Вместо этого вы должны дождаться ответа HTTPS. Идея состоит в том, чтобы прослушать end
событие, скомпоновать все куски, пока вы его не получите, и только затем что-то сделать с результатом. Вы вызывали ваш обратный вызов после первого куска, который мог бы работать, но не гарантированно.
Когда мы складываем эти вещи, мы получаем что-то вроде этого:
async function https_req (options) {
return new Promise(resolve => {
let result = ''
http.request(options, res => {
res.setEncoding('utf8')
res.on('data', chunk => { result += chunk })
res.on('end', resolve)
}).end()
})
}
Надеюсь, это очевидно, что это не надежное решение, не проверяет ошибки и т.д. На минимальном уровне вы вызываете его так:
ctx.body = await https_req(options)