Node.js 中 Promise 的执行顺序

Execution order of Promises in Node.js

我使用 Node.js v10.15.0

执行了以下代码
Promise.resolve()
  .then(() => console.log('A'))
  .then(() => console.log('B'))
  .then(() => console.log('C'))

setImmediate(() => console.log('IMMEDIATE'))

Promise.resolve()
  .then(() => console.log('D'))
  .then(() => console.log('E'))
  .then(() => console.log('F'))

由于我期望在输出后的完整功能中不涉及异步代码

A
B
C
D
E
F
IMMEDIATE

但我得到了...

A
D
B
E
C
F
IMMEDIATE

据我了解情况,setImmediate() 调用向我们表明,none console.log() 调用被推迟到下一个事件循环迭代。但是,为什么 console.log() 调用的顺序混淆了?

有两个 Promise.resolve()... 并行执行的承诺链。

A
D
B
E
C
F

是他们的预期顺序。

为了串联执行它们,应该是:

Promise.resolve()
  .then(() => console.log('A'))
  .then(() => console.log('B'))
  .then(() => console.log('C'))
  .then(() => Promise.resolve()) // no-op
  .then(() => console.log('D'))
  .then(() => console.log('E'))
  .then(() => console.log('F'))

the setImmediate() call shows us, that no console.log() calls get deferred to the next Event Loop iteration

实际上他们这样做 - 请记住,promise then 回调是 总是 异步的。

他们只是 运行 在事件循环的不同阶段,他们在不同的任务队列中排队。具体的NodeJS,详见文章https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

I expected following output

不要对独立的承诺链做任何假设。您可以并且应该期望的是 B 出现在 A 之后,C 出现在 B 之后,并且在另一个链中 E 出现在 [=18 之后=] 和 E 之后的 F。它们可以任意交错 1 - 如果您想确保顺序,请使用 then.

将 promise 彼此链接起来

1:规范详细说明了 promise 任务的排队方式,以便在不同的引擎实现之间保持一致,但这些细节应被视为无关紧要。