宏任務、微任務與Event Loop


說到宏任務和微任務,我們就不得不提 Event Loop

JS的本質是單線:

1. 一般來說,非阻塞性的任務采取同步的方式,直接在主線程的執行棧完成。

2. 一般來說,阻塞性的任務都會采用異步來執行,異步的工作一般會交給其他線程完成,然后回調函數會放到事件隊列中。

當主線程的任務執行完了(執行棧空了),JS會去詢問事件隊列

執行一個宏任務(先執行同步代碼)-->執行所有微任務-->UI render-->執行下一個宏任務-->執行所有微任務-->UI render-->......

根據HTML Standard,一輪事件循環執行結束之后,下輪事件循環執行之前開始進行UI render。即:macro-task任務執行完畢,接着執行完所有的micro-task任務后,此時本輪循環結束,開始執行UI render。UI render完畢之后接着下一輪循環。但是UI render不一定會執行,因為需要考慮ui渲染消耗的性能已經有沒有ui變動

 

哪些是宏任務、微任務呢?

推薦閱讀:https://juejin.im/post/5b73d7a6518825610072b42b

所以,明白哪些操作是宏任務、哪些是微任務就變得很關鍵,這是目前業界比較流行的說法:

宏任務


微任務

有些地方會列出來UI Rendering,說這個也是宏任務,可是在讀了HTML規范文檔以后,發現這很顯然是和微任務平行的一個操作步驟
requestAnimationFrame姑且也算是宏任務吧,requestAnimationFrameMDN的定義為,下次頁面重繪前所執行的操作,而重繪也是作為宏任務的一個步驟來存在的,且該步驟晚於微任務的執行

任務的優先級

宏任務macrotask:主代碼塊 > setImmediate > MessageChannel > setTimeout / setInterval (大部分瀏覽器會把DOM事件回調優先處理 因為要提升用戶體驗 給用戶反饋,其次是network IO操作的回調,再然后是UIrender,之后的順序就難以捉摸了,其實不同瀏覽器的表現也不太一樣,這里不做過多討論。)

微任務microtask:process.nextTick > Promise = MutationObserver

 

就是說任務執行的順序是建立與優先級之上的:

如果隊列已經有一個setTImeout的宏任務,后來又加入了主代碼的宏任務,會讓主代碼的的任務插隊。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM