1. 程式人生 > 其它 >瞭解js的巨集任務(macrotask)和微任務(microtask)以及Event-Loop

瞭解js的巨集任務(macrotask)和微任務(microtask)以及Event-Loop

JavaScript

首先,JavaScript是一個單執行緒的指令碼語言,所以就是說在一行程式碼執行的過程中,必然不會存在同時執行的另一行程式碼,就像使用alert()後進行列印,如果不關閉彈窗,則不會執行後續的列印操作

微任務與巨集任務的區別

巨集任務:

類似於去銀行辦理業務,櫃員同一時間只能為一個客戶辦理業務,因此每個客戶要想辦理業務就必須進行排隊領號,這裡的“客戶”=巨集任務,當櫃員處理完當前客戶的所有問題後,就會接待下一位客戶,廣播報號時也就意味著下一個巨集任務的開始。多個巨集任務的時候就是相當於排隊的客戶們。

常見巨集任務:

# 瀏覽器 Node
setTimeout
setInterval
setImmediate x
requestAnimationFrame x

任務佇列中的都是已經完成的非同步操作,而不是說註冊一個非同步任務就會被放在任務佇列中,就像銀行排隊叫號的時候你不在,那麼就需要重新領號,櫃員會直接進行下一位客戶的業務處理,也就是直接進入下一個巨集任務了

微任務:

在一個巨集任務執行的過程中,是可以新增微任務的,類似於櫃員處理當前客戶的時候,客戶手頭不止一個需求需要得到處理,有可能有多個業務需要辦理,而裡面的多個業務指的就是微任務,直到當前巨集任務中的微任務辦理結束後才會進行下一個巨集任務

常見微任務:

# 瀏覽器 Node
process.nextTick x
MutationObserver x
Promise.then catch finally

舉例:

setTimeout(() => {
    //執行後 回撥一個巨集事件
    console.log('內層巨集事件3')
}, 0)
console.log('外層巨集事件1');

new Promise((resolve) => {
    console.log('外層巨集事件2');
    resolve()
}).then(() => {
    console.log(
'微事件1'); }).then(()=>{ console.log('微事件2') })

列印結果

//外層巨集事件1
//外層巨集事件2
//微事件1
//微事件2
//內層巨集事件3

• 首先瀏覽器執行js進入第一個巨集任務進入主執行緒, 遇到setTimeout分發到巨集任務Event Queue中

• 遇到console.log()直接執行 輸出 外層巨集事件1

• 遇到Promise, newPromise直接執行 輸出 外層巨集事件2

• 執行then被分發到微任務Event Queue中

•第一輪巨集任務執行結束,開始執行微任務 列印 '微事件1' '微事件2'

•第一輪微任務執行完畢,執行第二輪巨集事件,列印setTimeout裡面內容'內層巨集事件3'

Event-Loop(只簡單說一下)

正因為js是一個單程序的語言,同一時間不能處理多個任務,所以何時執行巨集任務、微任務,我們就需要一個可以進行判斷邏輯的存在

每次辦理完一個業務,會詢問當前客戶是否還需要辦理其他業務檢查還有沒微任務需要處理)

客戶明確告知沒有業務需要辦理了,櫃員會去檢視後面是否還有客戶需要辦理業務(結束本次巨集任務後,檢查還有沒有未處理的巨集任務)

這個檢查的過程是持續進行的,每完成一個任務都會進行一次,而這樣的操作就被稱為Event Loop

以及還要明確的是,Event Loop只是負責告訴你該執行那些任務,或者說哪些回撥被觸發了,真正的邏輯還是在程序中執行的。

參考:

https://www.cnblogs.com/jiasm/p/9482443.html