1

1 引言

首先大家来看个面试题:

console.log('sync1')
setTimeout(function() {
    console.log('setTimeOut1')
},0)
var promise = new Promise(function(resolve){
    setTimeout(function() {
        console.log('setTimeoutPromise')
    }, 0)
    console.log('promise')
    resolve()
})
promise.then(() => {
    console.log('proThen')
    setTimeout(()=>{
        console.log('proThenSta')
    },0)
})
setTimeout(function() {
    console.log('lastSetTimeOut')
},0)
console.log('sync2')

哈哈哈,各位有没有很蒙圈?在此先公布正确答案:
sync1
promise
sync2
proThen
setTimeOut1
setTimeoutPromise
lastSetTimeOut
proThenSta

2 理论介绍

要理解这个题目首先要清楚事件循环机制对于宏任务和微任务的处理。宏任务和微任务表示异步任务的两种分类。在挂起任务时,JS引擎会将所有任务按照类别分到这两个队列中,首先在宏任务的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出微任务队列中的所有任务顺序执行;之后再取宏任务任务,周而复始,直至两个队列的任务都取完。
常用的宏任务:整体代码script、setTimeout、setInterval、setImmediate
常见的微任务:process.nextTick、MutationObserver、Promise.then catch finally

3 解析题目

首先第一遍同步执行,创建第一个宏任务。这时首先打印了 sync1 promise sync2
此时then函数有了一个微任务 然后打印了proThen
同时创建了 分别打印 setTimeOut1 setTimeoutPromise lastSetTimeOut 的三个宏任务
以及then函数里 还有一个proThenSta 的宏任务
这几个宏任务分别一次执行,于是有了上面的答案


小葱
95 声望3 粉丝