代码:
const promise1= new Promise((resolve,reject)=>{
console.log('promise1');
setTimeout(()=> {
resolve('success promise1')
})
})
const promise2 = promise1.then(() => {
console.log('success promise2');
return 666;
})
const promise3 = promise2.then(res => {
console.log('success promise3:', res);
return Promise.resolve(818);
})
promise3.then((res) => {
console.log('success promise4:',res);
})
setTimeout(()=> {
console.log('timer duration=10')
}, 10)
setTimeout(()=> {
console.log('timer duration=0')
}, 0)
console.log('just test')
顺序分析:
new Promise
内部代码直接执行,所以先输出promise1
,setTimeout
将回调函数交于定时器线程管理,待当前宏任务队列清空后立即推入宏任务队列并执行。
上一步new Promise
返回的promise
赋值给promise1
,而promise1
此时并未resolve
,所以将then
的内容缓存到[[PromiseFulfill/RejectReactions]]列表。待promise1
resolve之后,才将then
中的内容推入微任务队列。这里依赖promise1
的fullfilled
状态
promise3
的值依赖promise2
的状态,由于promise1
此时状态未改变,所以promise2
也未变。
遇到setTimeout
,交于定时器线程管理,10ms后若主线程任务已清空则将代码推入宏任务队列。
遇到setTimeout
,交于定时器线程管理,0ms后若主线程任务已清空则将代码推入宏任务队列。
直接输出just test。
第一次宏任务执行完毕,当前任务队列已清空。此时定时器线程将resolve('success promise1')
推入宏任务队列并执行,进入第二轮事件循环。
promise1
状态被改变,promise1.then
被推入微任务队列并执行。
promise2
状态被改变,promise2.then
被推入微任务队列并执行。
promise3
状态被改变,promise3.then
被推入微任务队列并执行。
微任务执行完毕,当前无任务,第二轮事件循环结束,定时器将console.log(timer duration=0)
推入宏任务队列,进入第三轮事件循环,输出timer duration=0
后第三轮事件循环结束。
此时若未过10ms,则等待至10ms后,将console.log('timer duration=10')
推入宏任务队列并执行,第四轮事件循环结束。
结果输出:
"promise1"
"just test"
"success promise2"
"success promise3:" 666
"success promise4:" 818
"timer duration=0"
"timer duration=10"
setTimeout
设置的时间,0和1都一样,如果设置为2,那么将晚与0或1执行,比如将promise1
的地方改成如下
setTimeout(()=> {
resolve('success promise1')
}, 2)
输出将变为:
"promise1"
"just test"
"timer duration=0"
"success promise2"
"success promise3:" 666
"success promise4:" 818
"timer duration=10"
————————————————
原文转自好友qingxuepeng