在探究的Event Loop(事件環, 以下簡稱EL)執行機制之前先思考以下一段程式碼的執行結果,然後在瀏覽器和Node中驗證你的答案。當然,如果兩個執行環境得出的結果是一樣的,那你可以關閉當前文件了
setTimeout(() => console.log('setTimeout1'), 0);
setTimeout(() => {
console.log('setTimeout2');
Promise.resolve().then(() => {
console.log('promise3');
Promise.resolve().then(() => {
console.log('promise4');
})
console.log(5)
})
setTimeout(() => console.log('setTimeout4'), 0);
}, 0);
setTimeout(() => console.log('setTimeout3'), 0);
Promise.resolve().then(() => {
console.log('promise1');
})
複製程式碼
單執行緒
要理解EL, 我們首先要理清楚js中的單執行緒。js中的單執行緒並不像很多人理解的單執行緒那麼簡單。js的主執行緒是單執行緒, 在主執行緒之外,還有microtask(微任務)佇列,macrotask(巨集任務,也叫task)佇列。
1.微任務
一個EL中只有一個microtask佇列,通常下面幾種任務被認為是microtask:
- promise(promise的then和catch才是microtask,本身其內部的程式碼並不是)
- MutationObserver
- process.nextTick(nodejs)
2.巨集任務
一個EL中可以有一個或者多個巨集任務佇列,每一個巨集任務都有一個特定的任務源。通常下面幾種任務被認為是macrotask:
- setTimeout
- setInterval
- setImmediate
- I/O
- UI rendering