-
宏任務(macro-task)
macro-task.png -
微任務(micro-task)
micro-task.png
同步任務與異步任務
eventloop.png
- 同步任務進入主線程,異步任務進入Event Table并注冊函數
- 當指定的事情完成時,Event Table會將這個函數移入Event Queue。
- 主線程內的任務執行完畢為空,會去Event Queue讀取對應的函數,進入主線程執行。
- 上述過程會不斷重復,也就是常說的Event Loop(事件循環)。
- js引擎存在monitoring process進程,會持續不斷的檢查主線程執行棧是否為空,一旦為空,就會去Event Queue那里檢查是否有等待被調用的函數。
宏任務與微任務
宏任務與微任務.png
微任務和宏任務皆為異步任務,但是微任務的優先級高于宏任務。
例子1:
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
執行結果為:script start, script end, promise1, promise2, setTimeout
因為Promise是微任務,主線程會在同步任務做完后先清空微任務隊列,再執行宏任務隊列的setTimeout
例子2:
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)
執行結果為:Promise1,setTimeout1,Promise2,setTimeout2
step1:
同步任務執行完畢,會去清空微任務,輸出Promise1,同時生成宏任務 setTimeout1,setTimeout2
step2:
去宏任務隊列查看,此時隊列最前面是 setTimeout1 ,所以執行setTimeout1,同時生成微任務Promise2
step3:
宏任務結束后再去查看微任務隊列,執行Promise2
step4:
微任務結束后再執行最后一個宏任務setTimeout2