想请教下我对于以下这段代码的理解是否正确:
new Promise((resolve, reject) => {
console.log(1);
resolve();
})
.then((a) => {
console.log(2);
new Promise((resolve,reject) => {
console.log(3);
resolve();
})
.then((c) => {
console.log(4);
})
.then((d) => {
console.log(6);
})
})
.then((b) => {
console.log(5);
});
输出是1 2 3 4 5 6
我疑惑的点主要在于:then
的回调究竟是什么时候放入微任务队列中的,特别是console.log(5)
和console.log(6)
这两个then
。
在参考了A+规范后,有这么一段话:promise.then(callback)
的回调必须在promise
变为fulfilled
之后调用。
首先执行代码块,Promise
构造函数直接输出1
,而后这个Promise
通过调用resolve
变为fulfilled
,因此将then(a=>)
放入微任务队列。接下来执行then(a=>)
的回调:
首先打印2
,然后new Promise
打印3
,调用resolve
状态变为fulfilled
。
因为这个Promise现在是fulfilled了,所以将then(c=>)
放入微任务队列。
所以现在的微任务队列:then((c)=>)
。按照我的理解,到目前为止,then((b)=>)
是不在微任务队列中的,所以关键就在于,then(b)和then(c)是什么时候进入微任务队列的呢?
注意
then(a=>)
的回调执行结束之后(此时c=>
已经在微任务队列里了),then(a=>)
的返回的 Promise 就 fullfill 了(注意这个 Promise 不是最开始的new Promise
)。于是,这个返回的Promise 的then(b=>)
被加入了微任务队列。promise1.then() 会返回一个新的 promise ,这个新的 promise 不是 promise1 。这个新的 promise 会根据 then 回调的执行结果来设置自己的状态,也就是只有回调正常结束了才会 fullfill 。
链式调用 then 时,每个 then 都是在各自不同的 promise 对象上调用的,而不是他们共享一个 promise 。
回答下评论:
问题在于,调用 then 就会将回调加入微任务嘛?不是的。只有当调用的 promise 已经 fullfilled 的时候,调用 then 才会将回调加入微任务。如果调用的 promise 的状态是 pending ,那么调用 then 不会加微任务,而只是将回调保存在 promise 的“属性(
[[PromiseFulfillReactions]]
)”里面。当 promise 的状态由 pending 变化为 fullfilled 的时候,这个属性的里的所有记录会被加进微任务队列。于是调用
then(a=>)
, 回调会被加入微任务,因为调用时 promise 已经 fullfilled 了。同时,他返回了一个新的 promise (记作promise1
吧) ,这个新的promise1
状态时 pending 。在新的promised1
上调用then(b=>)
(这个调用是同步的) ,这个回调不会被加入微任务,因为此时这个新的promise1
的状态是 pending ;这个回调会被记录在promise1
的[[PromiseFulfillReactions]]
里。当a=>
回调从微任务队列被取出并执行完之后,promise1
的状态由 pending 变化为 fullfilled ,它在[[PromiseFulfillReactions]]
中记录的回调会被放入微任务队列(b=>
入队)。c
,d
同理。