關於 macrotask 和 microtask 有很多文章文件,可以無限延伸深入。這裡只能先作簡單整理,至少有個大方向,以後再慢慢增補。
在瀏覽器這個執行環境裡,除了 JS 引擎,還有 Web API、event loop...等等其他部分。Web API 提供了一些好用的功能,例如 setTimeout
,或是網路請求 api。在執行這些要花時間的任務 (task/ macrotask) 時,為了不要把主執行環境卡住,瀏覽器會把非同步函式放進 task queue (它還有 event queue, callback queue...等其他 7749 種稱呼),等待 call stack 空了的時候執行。
常見的 macotask:解析 HTML、操控 DOM、使用者事件 (滑鼠、鍵盤...)、載入 script、網路請求、計時器。
microtask 來自 JS 程式碼本身,通常由 promise 產生。不管 promise 多快或何時 resolve,promise 的 .then/catch/finally
一定都是非同步進行,也就是當 promise 有結果後,這些處理函式的內容會被放進 microtask queue,一樣等到執行堆疊清空後執行。
event loop 可以想成一段不斷運行的程式,隨時檢查 call stack 和上述兩個 queue 的狀態,並按照順序執行任務。換句話說 event loop 協調不同任務間的執行順序,讓程式不會塞車 (並最終達成非同步的效果)。
執行環境示意圖:
source:https://www.datainfinities.com/10/event-loop-and-callback-queue-in-javascript
把非同步任務移去 queue 裡排隊這部分不難想像,困擾的是當同時有 macrotask 又有 microtask,它們之間又是以什麼順序執行?
先上一張圖:
source:這篇的問答區
以圖來說大致可以整理成在每一次 event loop 循環 (迭代) 中:
這個過程中有幾個特點:
用以上步驟看了一些程式碼然後就立刻翻船了,明天來寫。
參考資料:
https://ithelp.ithome.com.tw/articles/10221944
https://ithelp.ithome.com.tw/articles/10222737
https://www.linkedin.com/pulse/unraveling-javascript-event-loop-comprehensive-guide-michael-baker
https://slawinski.dev/blog/javascript-runtime-environment-web-api-task-queue-and-event-loop/
https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth
https://medium.com/@jain8siddharth8/the-javascript-event-loop-microtasks-and-macrotasks-7db6d918bc03