1、事件迴圈
大家都知道JavaScript是一門單執行緒語言
大白話講一下吧:什麼是單執行緒呢,就是主執行緒在執行程式碼時,只能從上往下一行一行執行,如果執行到某一行花費了很長時間,那麼,呵呵,沒辦法,後面的程式碼只能等著,如果執行到某一行,程式碼出錯了,呵呵,後面的也得不到執行。
但是,這樣肯定不行的。所以JavaScript
引入了同步非同步的概念,把比較耗時的程式碼放到非同步API中執行,不要去阻塞主執行緒。也就有了**事件迴圈(Event Loop)**的概念
事件迴圈(Event Loop):先會執行棧中的內容,棧中內容執行後執行微任務,微任務清空後再執行巨集任務,巨集任務會在棧中執行,不停的迴圈. 如果還是不懂概念,參考這裡
2、用三個框框解釋Event Loop
不知道大家遇到過js
執行順序的問題,什麼樣的組合都有,主要成員有以下幾個
setTimeout
Promise
setImmediate
Process.nextTick()
每次列印出的結果都是不按套路出牌。今天,我們就用三個框框搞懂它們,請看大螢幕。
2-1、總體介紹
看圖說話。圖中一共三個框框,分別是紅色(R)、綠色(G)、藍色(B)。
執行順序:先執行紅框,再執行藍框,最後執行綠框(輔助記憶:RGB)。 這裡我們要記住執行順序,以及每個框是用來幹什麼的。
2-2、紅框
紅框是呼叫棧,所有的程式碼必須在這裡執行,當在這裡執行程式碼時,如果產生了非同步任務,那麼就按照一定類別把該非同步任務放到藍框或者綠框裡。絕對不能阻塞紅框裡的其他程式碼執行。
2-3、藍框
藍框裡放的一個個任務叫microTask
,就是微任務的意思,當紅框程式碼執行完畢後,紅框就會從藍框中取出一個任務並執行,在執行過程中如果產生了其他非同步任務,那麼繼續放到藍框或者綠框裡。就這樣,藍框的一個個任務都被執行了。圖中列舉了幾個屬於microTask
任務的API
2-4、綠框
綠框裡放的一個個任務叫macroTask
,就是巨集任務的意思,當藍框裡的程式碼 執行完畢後,紅框就會從綠框裡取出一個任務並執行,在執行過程中如果產生了其他非同步任務,那麼繼續放到藍框或者綠框裡。就這樣,綠框的一個個任務都被執行了。圖中列舉了幾個屬於macroTask
任務的API
3、哪些是macroTask,哪些是 microTask
知道了每個框的作用以及總體的執行順序後,該說一下,哪些API
屬於microTask
(藍框),哪些API
屬於macroTask
(綠框)。
microtask
主要含:Promise
、process.nextTick
、MutaionObserver
maicrotask
主要含:setTimeout
、setInterval
、setImmediate
、I/O
、UI互動事件
以上列出的這些API
各自屬於哪個任務必須要記住。
4、練習
說了那麼多,來做幾個練習吧。 先來個一年級的
setTimeout(() => {//放到了綠框裡
console.log(2)
}, 0);
new Promise(function (resolve) { resolve() }).then(function () {
console.log(3)
})//放到了藍框裡
console.log(1)//預設在紅框裡,不動
複製程式碼
以上程式碼的結果是1、3、2
解釋一波吧:
- 這段程式碼首先整體作為一個巨集任務(
macroTask
)進入到紅框。 - 先遇到
setTimeout
,那麼將其回撥函式註冊後分發到巨集任務中,就是綠框裡邊。 - 然後遇到了
Promise
,then
函式分發微任務到微任務中,就是藍框裡。 - 遇到
console.log()
,立即執行。 - 到這裡,整體程式碼作為第一個巨集任務就執行結束了。接下來,該去藍框看看了,發現有
then
,執行。 - 然後再到綠框裡拿出
setTimeout
的註冊回撥函式,執行 - 結束。
再來一道複雜點兒的吧
console.log(1)
setTimeout(() => {
console.log(2);
process.nextTick(function () {
console.log(3);
})
}, 0);
process.nextTick(function () {
console.log(4)
})
new Promise(function (resolve) {
console.log(5);
resolve()
}).then(function () {
console.log(6)
})
複製程式碼
以上程式碼執行結果為:1、5、4、6、2、3
分析過程留給大家吧,只要按照我們一開始說的,把所有的非同步任務分門別類的放到對應的框框裡,然後再按照RGB的順序去執行,我相信,你能做對的。