首先你們來看個面試題:javascript
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
proThenStajava
要理解這個題目首先要清楚事件循環機制對於宏任務和微任務的處理。宏任務和微任務表示異步任務的兩種分類。在掛起任務時,JS引擎會將全部任務按照類別分到這兩個隊列中,首先在宏任務的隊列(這個隊列也被叫作 task queue)中取出第一個任務,執行完畢後取出微任務隊列中的全部任務順序執行;以後再取宏任務任務,周而復始,直至兩個隊列的任務都取完。 經常使用的宏任務:總體代碼script、setTimeout、setInterval、setImmediate 常見的微任務:process.nextTick、MutationObserver、Promise.then catch finally
首先第一遍同步執行,建立第一個宏任務。這時首先打印了 sync1 promise sync2
此時then函數有了一個微任務 而後打印了proThen
同時建立了 分別打印 setTimeOut1 setTimeoutPromise lastSetTimeOut 的三個宏任務
以及then函數裏 還有一個proThenSta 的宏任務
這幾個宏任務分別一次執行,因而有了上面的答案面試