背景
以前经常看见的题都是then链加setTimeout加setInterval等这些常见的宏任务微任务顺序题目,最近遇到加finally问题,着实有点迷,总结一下
题目
console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
Promise.resolve(3).then(res => {
console.log(res);
}).then(res => {
Promise.resolve(4)
}).finally(function(res) {
console.log(res);
}).then(res => console.log(res))
Promise.resolve(5).then(res => {
console.log(res)
})
/*
最终的结果为:
1
3
5
undefined
undefined
2
*/
解释
- 首先,同步执行代码,打印1
- 遇见setTimeout宏任务,添加宏任务队列,宏任务队列[2]
- 静态方法直接决议,把3添加到微任务队列中,
- 因为第一个then还在微任务队列中还没执行,所有后面的链式调用都没能执行
- 继续执行第二个直接决议5,添加到微任务队列中,微任务队列中有[3, 5]
- 没有同步代码,执行微任务3.打印3,then没有显式返回,所以返回了默认的用Promise.resolve()包装的undefined,并把then加入到微任务队列中
- 继续执行微任务中的代码,打印5,
- 继续执行微任务队列中Promise.resolve(4)这一块代码,这句代码就是直接决议了一个期约,没有什么用,也不作为返回值,所以还是默认返回了Promise.resolve()包装undefined的期约实例,把finally执行程序添加到为任务队列
- 继续执行微任务队列中finally的执行程序,打印了undefined,因为finally没有显式返回期约,所以直接原样返回父期约,即undefined,添加then处理程序到微任务队列
- 执行then处理程序,打印undefined
- 微任务处理完毕,检查宏任务队列,打印2
如果解释有什么问题,希望各路神仙指正