Express 中的回调与等待性能
Posted
技术标签:
【中文标题】Express 中的回调与等待性能【英文标题】:Callback vs Await Performance in Express 【发布时间】:2018-09-16 05:21:49 【问题描述】:人们说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)
...
这将打印出1
,然后是2
,这意味着除非异步函数完成,否则我们将无法退出/register
处理程序并重定向。
在下面的版本中,我们在then
中使用带有回调的promise。
router.get('/register', (req, res) =>
res.redirect('/')
doSomethingAsync().then(() =>
console.log(1)
)
router.get('/', (req, res) =>
console.log(2)
...
这将打印出2
,然后是1
,这意味着我们可以立即退出并重定向用户。
第二种方式不是更好的性能吗?还是它们实际上是一样的?
【问题讨论】:
我很确定这两种方式都有相同的性能。但是如果你想确定,你可以使用 console.timer("myTimer") 然后使用 console.timeEnd("myTimer") 来设置它使用的时间。 【参考方案1】:人们说
async/await
只是为 promise 编写回调的另一种方式。但是,我觉得它们好像不能互换;
这是不正确的,它们确实可以互换。事实上,async/await
让您做事比使用简单的 Promise 更容易,因为 await
表达式可以无缝地插入到几乎任何控制流逻辑中,而使用简单的 Promise 则不能这样做,并且需要使用连续的.then()
调用来链接它们。
事实上,回调在 Express 中会更好,因为它会立即将结果返回给用户。这是正确的吗?
没有。回调是异步传递数据的不同机制;它不是“立即”,也不是明显更快,并且使用 Promise 编程的好处远远超过诉诸 callback hell 的任何可忽略的性能影响。另外,你的第二个例子不是真正的回调,它是一个承诺链。
这将打印出
1
,然后是2
,这意味着除非异步函数完成,否则我们将无法退出/register
处理程序并重定向。
这是不正确的。 await
是非阻塞的。只要doSomethingAsync()
被调用,async
function 就会返回给调用者,async
function's 返回值是在调用console.log(1)
之后解析的promise。
这将打印出
2
,然后是1
,这意味着我们可以立即退出并重定向用户。第二种方式不是更好的性能吗?还是它们实际上是一样的?
这两个 sn-ps 在算法上是相同的,并且由于 console.log(2)
依赖于客户端的浏览器执行由 res.redirect('/')
指示的 HTTP 请求,这与 doSomethingAsync()
无关,因此您实际上有一个竞争条件,并且既不能保证日志的顺序。它的性能也与使用await
的示例没有什么不同。
【讨论】:
我认为在快速发展的 javascript 世界中,像这样的解释应该由试图替换功能 A 的功能 B 提供。否则人们只会认为功能 A 已经过时\坏\工作不同 感谢您的详细解释!为了确保,当你说它调用下面的指令并立即返回时,如果下面有一行使用 await 的结果会发生什么? ` router.get('/register', async (req, res) => res.redirect('/') var result = await doSomethingAsync(); console.log(1); console.log(result) `这里,你说console.log(1)
会在promise解析之前被调用,但是console.log(result)
也会被调用吗?
“当你说它调用下面的指令时等待”——我没有这么说。我说它调用doSomethingAsync()
。然后该函数立即返回,await
之后的语句直到doSomethingAsync()
返回的承诺被解决后才会被调用。以上是关于Express 中的回调与等待性能的主要内容,如果未能解决你的问题,请参考以下文章