开始之前先理解几个Promise操作,
- 一个Promise resolve 或 reject 之后会吧 身后一个then回调函数也就是 onfulfilled 或 onRejected 加入微任务队列。详细内容见ECMAScript® 2025的27.2.5.4.1 PerformPromiseThen。
- Promise.then调用之后 会返回一个新promise。详细内容见ECMAScript® 2025的27.2.5.4 Promise.prototype.then。
题目:以下代码会输出哪些内容
Promise.resolve()
.then(()=>{
console.log(0)
return Promise.resolve(4)
})
.then((res)=>{
console.log(res)
})
Promise.resolve()
.then(()=>{
console.log(1)
})
.then(()=>{
console.log(2)
})
.then(()=>{
console.log(3)
})
.then(()=>{
console.log(5)
})
.then(()=>{
console.log(6)
})
我们正常顺序往下看,Promise.resolve()是立即执行的同步任务,并返回一个状态为fulfilled的Promise,当一个Promise状态为fulfilled的时候,将身后的第一个then方法中的第一个回调函数,也就是onfulfilled方法,放入微任务队列。第二个then的回调则是要等第一个then的状态发生改变才会被推进微队列。
// 微任务队列伪代码是这样的
[
()=>{
console.log(0)
return Promise.resolve(4)
}
]
运行到第二个Promise.resolve(),返回的是一个状态为fulfill的Promise,将身后的第一个then中onfulfilled方法放进微任务队列。依次调用下面所有的then让因为then产生的新Promise进入padding状态。其他的promise都在pedding所以不会有新的微任务进入队列。
// 微任务队列伪代码
[
()=>{
console.log(0)
return Promise.resolve(4)
},
()=>{
console.log(1)
}
]
执行微任务队列中的任务 输出 0。注:根据PromiseA+规范中规定,在一个then中return 一个Promise,会让因为调用then产生的Promise的状态和return的这个Promise状态同步,同步方式为将调用return的这个Promise的then方法,在其中完成因为then调用产生的Promise的这个行为推入微任务队列。这个Promise还是pedding状态,所以下一个then中的回调不会进入微任务队列。
// 微任务队列伪代码
// 注 这里是Promise fulfilled 是黑盒操作,不关心里面执行了什么,
// 只需要知道它会完成这个Promise即可
[
()=>{
console.log(1)
},
Promise.resolve(4).then(()=>{(Promise fulfilled)})
]
输出 1,输出1的那个Promise执行完成 将下一个then中的回调推入微任务队列。
// 微任务队列伪代码
[
Promise.resolve(4).then(()=>{(Promise fulfilled)}),
()=>{
console.log(2)
},
]
无新任务入队,执行微任务队列中的任务,调用Promise.resolve(4).then(),将then里面的回调推进微任务队列。
// 微任务队列伪代码
[
()=>{
console.log(2)
},
()=>{(Promise fulfilled)}
]
无新任务入队,执行微任务队列中的任务 ,输出 2。
// 微任务队列伪代码
[
()=>{(Promise fulfilled)}
]
输出2的那个Promise执行完成 将下一个then中的回调推入微任务队列。
// 微任务队列伪代码
[
()=>{(Promise fulfilled)},
()=>{
console.log(3)
},
]
无新任务入队,执行微任务队列中的任务,完成 return Promise.Resolve(4)这个Promise,这个Promise完成,那它上级的Promise也就完成了,将下一个then中的回调推入微任务队列。
// 微任务队列伪代码
[
()=>{
console.log(3)
},
(res)=>{
console.log(res)
}
]
无新任务入队,执行微任务队列中的任务,输出3。 输出3的那个Promise执行完成 将下一个then中的回调推入微任务队列
// 微任务队列伪代码
[
(res)=>{
console.log(res)
}
()=>{
console.log(5)
},
]
无新任务入队,执行微任务队列中的任务,输出4。
无新任务入队,执行微任务队列中的任务,输出5。输出 5 的那个Promise执行完成 将下一个then中的回调推入微任务队列。
[
()=>{
console.log(6)
},
]
无新任务入队,执行微任务队列中的任务,输出6,输出 6 之后就得到这题的全部输出, 全部输出是 0,1,2,3,4,5,6.