Koa JS - Невозможно отправить ответ после вызова API. Всегда получаю 404

1

Вот мой код:

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
})

Но он всегда дает "Не найдено".

Я также хочу знать, почему это происходит. И что я должен сделать, чтобы он работал.

Теги:
koa
koa2

1 ответ

1
Лучший ответ

Таким образом, это пример смешения кода на основе обратного вызова и кода на основе обещаний, что делает вещи немного сложными. Что происходит, так это: 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)
  • 1
    Спасибо большое ... Работает отлично. Я перепробовал все, кроме возвращения обещания. Теперь я понимаю, как это использовать. Это спасло мой день. Еще раз спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню