【问题标题】:async / await in node / express does not seem to wait for Promise to resolvenode / express 中的 async / await 似乎没有等待 Promise 解决
【发布时间】:2018-02-21 12:35:27
【问题描述】:

我在 express 之外有一个简单的脚本来测试它,我的脚本按预期工作。但是,下面的代码似乎不符合我的期望。

代码

async function getTest(type, key) {
  var body = await tloader.pload(type, key)
  console.log(body)
  return body
}

router.get('/pages/test', function(req, res) {
  console.log("Running test...")
  var content = getTest('tplt', 'primary')
  console.log(content)
  res.send(content)
  console.log(content)
})

控制台日志:

Promise { <pending> }
Promise { <pending> }
<html>
  <head>
  </head>
  <body>
    <p>Hello World - I love you all! It works!</p>
  </body>
</html>

Promise 仅在发送内容后才被解析(也发送为 { } object

不管怎样,包含承诺的代码是:

var pload = function(type, tname) {
    return new Promise( function(resolve, reject) {
        var key = keybase + type + ":" + tname
        rcli.get(key, function(err, res) {
            if (err) {
                reject(err)
            } else {
                resolve(res)
            }
        })
    })
}

(而且,是的,我知道我没有 try catch 来处理 promise 拒绝。)

【问题讨论】:

  • getTest() 返回一个承诺。您正在调用它,但没有使用 .then()await 来等待承诺完成。因此,您在getTest() 完成之前调用res.send()。您需要使用await getTest()getTest().then() 来实际等待promise 解决。如果使用await getTest(),则必须将包含函数声明为async
  • 我想我现在明白了。当效果是创建同步行为时,'await' 必须在异步函数中,这有点奇怪。

标签: node.js express promise async-await


【解决方案1】:

您的async 函数本质上是一个“承诺”。

router.get('/pages/test', function(req, res) {
  console.log("Running test...")
  getTest('tplt', 'primary').then(content => {
    console.log(content)
    res.send(content)
    console.log(content)
  });
})

或者,您也许可以在 express 回调中使用 async/await,我不确定 express 将如何处理。

router.get('/pages/test', async function(req, res) {
  console.log("Running test...")
  const content = await getTest('tplt', 'primary');
  console.log(content)
  res.send(content)
  console.log(content)
})

【讨论】:

  • 好的,这行得通...谢谢。但是:我不明白为什么它在那里工作,而不是在我的 getTest 函数中?这也使用 await 来等待 Promise 在函数内解决,并且控制台记录一个未解决的 Promise。我担心这是一个短暂或意外的修复......
  • async 函数在 express 中可以正常工作,唯一的要求是如果您不接受 next() 参数,则必须处理响应,但这也是普通函数所必需的。跨度>
【解决方案2】:
async function getTest(type, key) {
  var body = await tloader.pload(type, key)
  return body
}

router.get('/pages/test', async function(req, res) {
  console.log("Running test...")
  var content = await getTest('tplt', 'primary')
  console.log(content)
  res.send(content)
  console.log(content)
})

我们知道,如果我们将任何普通函数转换为异步函数,那么它将作为 Promise 返回,因为每个 Promise 都必须由 (then function) 或 (await 关键字) 解析。当你的路由函数没有看到 promise resolver 关键字时,它会立即退出堆栈,所以如果你想让你的路由函数等待直到 promise resolve,你必须让你的路由函数异步,然后等待 getTest 来获取值。

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2018-09-28
    • 2018-05-25
    • 2015-08-18
    • 1970-01-01
    相关资源
    最近更新 更多