您看到的输出是因为Microtask 11
微任务直到Microtask 1
的微任务运行才会排队,此时Microtask 2
的微任务已经在队列中等待.因此,顺序是(跳过一些细节;更多信息如下):
Microtask 1
个队列微任务
Microtask 2
个队列微任务
- Task is compelete, start processing microtasks:
- Execute microtask queued in #1
- 输出
Microtask 1
Microtask 11
个队列微任务
- Execute microtask queued in #2
- 输出
Microtask 2
Microtask 21
个队列微任务
- Execute microtask queued in #3.1
- Execute microtask queued in #3.2
因此,
Microtask 1
Microtask 2
Microtask 11
Microtask 21
100:编写依赖于断开的Promise Chains/微任务序列的执行顺序的代码是自找麻烦的.:-)你只能根据已经达成的promise 进行推理,当然,在正常情况下,你不知道promise 什么时候会达成(甚至if).相反,如果您需要特定的订单,请将链条连接到ensure订单.
再次跳过细节:为了保持简短和清晰,我对主要解释中的内容进行了一些润色,但为了准确起见,我们来看看:
Promise.resolve()
.then(() => console.log("Microtask 1"))
.then(() => console.log("Microtask 11"));
...就这样,忽略了让事情变得简单的第二条promise 链.
以下是代码执行方式(我的blog post On Promise术语在阅读以下内容时可能会有所帮助):
- 执行
Promise.resolve()
,创建使用值undefined
实现in this particular case的promise .
- 执行
.then(() => console.log("Microtask 1"))
,创建一个新函数,并使用它在第1步中的promise 上调用then
.这将创建并返回一个新promise ,in this particular case,将微任务排队以调用该函数,因为该promise 已经兑现.
- 执行
.then(() => console.log("Microtask 11"))
,创建一个新函数,并使用它在第2步中的promise 上调用then
.这将创建并返回一个新的promise (我们在该代码中丢弃它),并且由于第2步中的promise 仍然悬而未决,因此将该函数作为履行处理程序添加到其中.
- 运行此代码的任务结束,因此JavaScript引擎处理微任务队列:
- 执行队列中的第一个微任务:
- 调用函数Logging
Microtask 1
.
- 由于函数返回
undefined
,而不是promise 或其他thenable,因此引擎用undefined.
履行步骤2中的promise (如果函数已返回promise 或其他支持,则promise 将改为resolved to,即返回的promise ).
- 将微任务排队以调用在第3步中在该promise 上注册的履行处理程序,该处理程序在被调用时将记录
Microtask 11
.
- 执行队列(remember that we're ignoring the other promise chain in this description, so in this case the next microtask is the one logging 104 that was just added to the queue, not the one logging 106)中的下一个微任务:
- 调用函数Logging
Microtask 11
.
由于该函数返回undefined
,这不是promise 或其他使能,因此引擎用undefined.
履行步骤3中的promise
- 这不会做任何事情,因为该promise 没有注册任何履行处理程序.