在JS的event loop
中,有兩種任務隊列microtasks
和macrotasks
promise
microtasksoop
macrotaskscode
在一個事件循環event loop的週期中,一個task應該從macrotask隊列開始執行。當這個macrotask結束後,全部的microtasks將在同一個cycle中執行。
且在microtasks執行時還能夠加入更多的microtask,而後一個一個的執行,直到microtask隊列清空。server
console.log('start') const interval = setInterval(() => { console.log('setInterval') }, 0) setTimeout(() => { console.log('setTimeout 1') Promise.resolve() .then(() => { console.log('promise 3') }) .then(() => { console.log('promise 4') }) .then(() => { setTimeout(() => { console.log('setTimeout 2') Promise.resolve() .then(() => { console.log('promise 5') }) .then(() => { console.log('promise 6') }) .then(() => { clearInterval(interval) }) }, 0) }) }, 0) Promise.resolve() .then(() => { console.log('promise 1') }) .then(() => { console.log('promise 2') })
event loop1:
macrotasks: [主程序代碼]
microtasks: []隊列
執行macrotasks隊列,也即執行主程序代碼,收集macro或micro的tasks
輸出: 'start'
收集的macrotasks(下次循環的): [setInterval, setTimeout]
收集的microtasks(當前循環的): [Promise]事件
macrotasks隊列執行完畢,這時候microtasks: [Promise]不爲空,執行microtasks隊列
輸出: 'promise1'
輸出 : 'promise2'
這時候microtasks爲空io
下次循環開始以前的隊列狀態
macrotasks: [setInterval, setTimeout]
microtasks: []console
event loop2:
執行macrotasks隊列
執行setInterval
輸出:'setInterval',且收集setInterval到下次循環的macrotasks中
執行setTimeout
輸出:'setTimeout 1',且收集Promise到當前循環的microtasks: [Promise]event
因爲當前循環的microtasks不爲空,執行隊列中的任務Promise
輸出:'promise3'
輸出: 'promise4'
收集setTimeout到下次循環的macrotasks中
這時候microtasks爲空class
下次循環開始以前的隊列狀態
macrotasks: [setInterval, setTimeout]
microtasks: []
event loop3:
執行macrotasks隊列
執行setInterval
輸出: 'setInterval',且收集setInterval到下次循環的macrotasks: [setInterval]中
執行setTimeout
輸出: 'setTimeout2',且收集Promise到當前的microtasks: [Promise]
因爲當前循環的microtasks不爲空,執行隊列中的任務Promise
輸出: 'promise5'
輸出: 'promise6'
清除定時器clearInterval,因此下次循環的macrotasks的setInterval被清除
下次循環開始以前的隊列狀態
macrotasks: []
microtasks: []
event loop4:
因爲macrotasks爲空,和microtasks爲空,程序處於等待狀態。
上面程序總的輸出結果是
// event loop1 start promise 1 promise 2 // event loop2 setInterval setTimeout 1 promise 3 promise 4 // event loop3 setInterval setTimeout 2 promise 5 promise 6