首页 > 解决方案 > JS Promise 在 nodejs 版本之间执行顺序不一致

问题描述

我正在阅读有关 nodejs promise here的文章。

然后我尝试运行以下示例代码(来自文章)

const p = Promise.resolve();

(async () => {
  await p; console.log('after:await');
})();

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));

节点版本之间的结果不一致。使用 node v10 远离所有其他版本。

我正在使用Mac。

v8.17.0
after:await
tick:a
tick:b

v10.20.1
tick:a
tick:b
after:await

v12.17.0
after:await
tick:a
tick:b

v14.3.0
after:await
tick:a
tick:b

文章说 v10 引入了一项重大更改以纠正执行顺序,而 v8 的行为是一个错误。但是,当我使用 v12 和 v14 进行测试时,它们给出的结果与 v8 相同。

谁能向我解释为什么会这样?

在此处输入图像描述

标签: node.jsasync-awaites6-promise

解决方案


这是由于规范中的这种更改现在允许短路await promiseInstance不会在内部包装promiseInstance到新的Promise中,因此节省了两个滴答声(一个用于等待promiseInstance,一个用于唤醒异步功能)。

这是规范补丁作者的详细文章,也恰好是 v8 开发人员。在那里,他们解释了这种行为实际上是如何在 nodejs v.8 中出现的,但到那时却违反了规范,即一个错误,他们在 v.10 中修复了,在这个补丁使它成为官方的做法之前,它得到了直接在v8引擎中实现。

因此,如果您希望在此补丁之前应该发生的内联版本是

const p = Promise.resolve();

new Promise((res) => p.then(res)) // wait for p to resolve
  .then((res) => Promise.resolve(res)) // wake up the function
  .then((res) => console.log('after:await'));

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));

虽然补丁使它

const p = Promise.resolve();

p.then(() => console.log('after:await'));

p.then(() => console.log('tick:a'))
 .then(() => console.log('tick:b'));

推荐阅读