- 宏任務隊列可以有多個,微任務隊列只有一個;
- 主線程上的任務是第一個宏任務;
-
會建立宏任務的有:setTimeOut、 setInterval、 requestAnimationFrame
- 會建立微任務的有:Promise的回調、 process.nextTick
- 當有一個宏任務隊列執行完畢后,會執行微任務隊列中的全部內容,然后執行另一個宏任務隊列,如此反復
js代碼執行機制基本是這樣的:當遇到3中的內容時建立新的宏任務,遇到4中的內容時將其加入微任務,然后按5中的順序執行。結合下面的例子來分析一下:
console.log("1") // setTimeOut函數不設置時間 setTimeout ( () => { console.log('2') new Promise( (resolve => { console.log("3") resolve() })) .then ( () => console.log("4")) }) new Promise ( (resolve, reject) => { console.log("5") resolve() }) .then( () => console.log('6')) setTimeout ( () => { console.log('7') }) console.log("8")
*測試發現setTimeOut不加時間與設置時間為0效果相同,都是等主線程上的代碼執行完后立即執行
分析:
js代碼從上到下執行,先遇到console.log(1),將其加入主線程的宏任務隊列,然后發現setTimeOut,為其創建第二個宏任務隊列並將其加入,其中代碼先不執行,然后遇到Promise,將其中的console.log(5)加入主線程的宏任務隊列,將then回調函數中的內容加入微任務隊列,繼續往下發現第二個setTimeOut,將其放入第三個宏任務隊列,最后將console.log(8)放入主線程宏任務隊列,到此,代碼已經完成了在不同隊列中的分布,詳細情況為:
接下來開始執行第一個宏任務隊列,分別打印1,5,8,然后執行微任務隊列,打印6,微任務隊列變為空。接着執行第二個宏任務隊列,開始執行第一個setTimeOut中的代碼:先后打印 2,3,並將回調函數中的console.log(4)加入微任務。此時第二個宏任務隊列執行完畢,開始執行微任務隊列,打印 4。接着執行第三個宏任務隊列,打印 7。執行完畢。所以最終輸出順序為:15862347。
個人理解,若有錯誤,歡迎指正