正常情況下,JavaScript的任務是同步執行的,即執行完前一個任務,然后執行后一個任務。只有遇到異步任務的情況下,執行順序才會改變。
這時,需要區分兩種任務:正常任務(task)與微任務(microtask)。它們的區別在於,“正常任務”在下一輪Event Loop執行,“微任務”在本輪Event Loop的所有任務結束后執行。
console.log(1); setTimeout(function() { console.log(2); }, 0); Promise.resolve().then(function() { console.log(3); }).then(function() { console.log(4); }); console.log(5); // 1 // 5 // 3 // 4 // 2
上面代碼的執行結果說明,setTimeout(fn, 0)
在Promise.resolve
之后執行。
這是因為setTimeout
語句指定的是“正常任務”,即不會在當前的Event Loop執行。而Promise會將它的回調函數,在狀態改變后的那一輪Event Loop指定為微任務。所以,3和4輸出在5之后、2之前。
正常任務包括以下情況。
- setTimeout
- setInterval
- setImmediate
- I/O
- 各種事件(比如鼠標單擊事件)的回調函數
微任務目前主要是process.nextTick
和 Promise 這兩種情況。
原文鏈接:http://javascript.ruanyifeng.com/advanced/timer.html