Express 中的回调与等待性能

1st*_*eap 5 asynchronous callback node.js express web

人们说这async/await只是为 Promise 编写回调的另一种方式。但是,我觉得它们似乎不可互换;事实上,回调在 Express 中会更好,因为它会立即将结果返回给用户。这样对吗?

在下面的示例中,假设我们不关心 的结果doSomethingAsync(),但想立即重定向。在这里,我们使用await.

router.get('/register', async (req, res) => {
    res.redirect('/')           
    await doSomethingAsync()
    console.log(1)
}

router.get('/', (req, res) => {
    console.log(2)
    ...
}
Run Code Online (Sandbox Code Playgroud)

这将打印出1, then 2,这意味着/register除非异步函数完成,否则我们将无法退出处理程序和重定向。

在下面的版本中,我们在then.

router.get('/register', (req, res) => {
    res.redirect('/')           
    doSomethingAsync().then(() => {
        console.log(1)
    })
}

router.get('/', (req, res) => {
   console.log(2)
   ...
}
Run Code Online (Sandbox Code Playgroud)

这将打印出2, then 1,这意味着我们可以立即退出并重定向用户。第二种方式不是更好的性能吗?或者它们实际上是一样的?

Pat*_*rts 10

人们说这async/await只是为 Promise 编写回调的另一种方式。但是,我觉得它们似乎不可互换;

这是不正确的,它们确实可以互换。事实上,与使用普通 Promise 相比,它async/await可以让您更轻松地做事,因为await表达式可以无缝地插入到几乎任何控制流逻辑中,而使用普通 Promise 则无法这样做,并且需要使用顺序.then()调用将它们链接起来。

事实上,回调在 Express 中会更好,因为它会立即将结果返回给用户。这样对吗?

不。回调是异步传递数据的不同机制;它不是“立即”,也不是明显更快,并且使用 promise 编程的好处远远超过诉诸回调地狱的任何可忽略不计的性能影响。此外,您的第二个示例不是真正的回调,而是一个承诺链。

这将打印出1, then 2,这意味着/register除非异步函数完成,否则我们将无法退出处理程序和重定向。

那是不正确的。await是非阻塞的。该async函数返回给调用者一旦doSomethingAsync()被调用,以及async函数的返回值是解决后一个承诺console.log(1)已被调用。

这将打印出2, then 1,这意味着我们可以立即退出并重定向用户。第二种方式不是更好的性能吗?或者它们实际上是一样的?

这两个片段在算法上是相同的,并且由于console.log(2)依赖于客户端的浏览器执行由 指示的 HTTP 请求,res.redirect('/')这与 无关doSomethingAsync(),因此您实际上有一个竞争条件,并且日志的顺序都不能保证。它的性能也没有什么不同比使用的例子await