天天看點

事件循環、宏任務、微任務

*宏任務*:在js中,在主線程上執行的任務叫宏任務,常見的有:

1渲染事件

使用者互動事件

js腳本

網絡請求、檔案讀寫完成事件

延遲事件(定時器)

普通任務隊列、延遲隊列中的任務都屬于宏任務。

為了讓這些事件有條不紊的進行,js引擎需要對執行的順序做一定的安排,v8其實采用是一種隊列的方式來存儲這些任務,即先進來的先執行。

*微任務*:對于每個宏任務而言,其内部都有一個微任務隊列,那為什麼要引入微任務?微任務在什麼時候執行?

引入微任務的初衷是為了解決異步回調問題,如果把異步回調放在宏任務,會造成卡頓。為了解決這一問題,v8引入微任務,在每一個宏任務中定義一個微任務隊列,當該宏任務執行完成,會檢查其中的微任務隊列,如果為空則執行下一個宏任務,如果不為空,則依次執行微任務,執行完成采取執行下一個宏任務。常見的微任務有:

MutationObserver

Promise.then(或.reject)以及以Promise為基礎開發的其他技術(比如fetch API)

v8垃圾回收機制

nextTick

事件循環--js運作機制(eventLoop)

例子:

分析一下:

1)剛開始整個腳本作為一個宏任務來執行,是以先列印start和end

2)setTimeout 作為一個宏任務放入宏任務隊列

3)Promise.then作為一個為微任務放入到微任務隊列

4)當本次宏任務執行完,檢查微任務隊列,發現一個Promise.then, 執行5)接下來進入到下一個宏任務——setTimeout, 執行

1)一開始整段腳本作為第一個宏任務執行

2)執行過程中同步代碼直接執行,宏任務進入宏任務隊列,微任務進入微任務隊列

3)目前宏任務執行完出隊,檢查微任務隊列,如果有則依次執行,直到微任務隊列為空

4)執行浏覽器 UI 線程的渲染工作

5)檢查是否有Web worker任務,有則執行

6)執行隊首新的宏任務,回到2,依此循環,直到宏任務和微任務隊列都為空

繼續閱讀