iT邦幫忙

0

[學習筆記] JavaScript - Event Loop (2) : Macrotask and Microtask

  • 分享至 

  • xImage
  •  

本篇內容參考連結
JS 原力覺醒 Day15 - Macrotask 與 MicroTask
我知道你懂 Event Loop,但你了解到多深?

Macrotask and Microtask

Definition

在(1)中了解了一些基本的Event Loop概念, 接下來就可以開始了解Macrotask和Microtask.首先Web API中, 在一些有非同步特性的目的達成後, 會把相對應的callback函式丟到Event Queue, 而這些函式需要達成的任務, 就是Macrotask. 其實在(1)中描述的就是Marcotask的機制. 而Microtask, 通常是由Promise產生, 在裡面用到的.then/.catch函式會以非同步的方式執行.舉Promise來說, 當Promise的callback內容執行完成, 狀態也再也不是pending時, .then或.catch裡面的函式, 就會被丟到Queue裡面等待執行, 而這些被推送的任務, 就是Microtask.

Event Queue vs Job Queue

相對於管理Web API所屬事件的Macrotask的Event Queue. Promise產生的Microtask也有自己的Queue, 在JS中被稱為Job Queue, 而其運作的方式也有點不一樣. 在 Event Queue 裡面的每個 Macrotask 執行完畢後, 就算 Event Queue 裡面還有其他的 Task, JS 引擎依舊會優先執行 Microtask Queue 裡面的所有 Task. 參照下面示意圖會更清楚
Event Loop示意圖

可以直接放置Code進去Microtask的函式 : queueMicrotask

queueMicrotask(() => {
  /* code to run in the microtask here */
});

How Macrotask and Microtask works

可參考官方文件Process Model
簡體中文版本

在官方文件可以有完整的model來描述整個event loop的流程, 這邊就大概點一些重點

  1. 首先確認 Macrotask是否有至少有一個已經在等待的函式.
    • 遵守FIFO的原則, 從Event Queue 中抽離一個callback函式, 並放入到call stack執行
  2. 執行Microtask的檢查(microtask checkpoint).
    • 由於觸發的時機點很多, 必須需要一個Flag來避免同一時間重複檢查.
    • 假如Job Queue不為空, 則從中抽離函式並放到call stack執行, 直到全部執行完
  3. 執行渲染的部分, 之後再慢慢細細品嘗

再來直接看一段程式

setTimeout(() => console.log("timeout")); // Macrotask

queueMicrotask(() => console.log("microtask")); // Microtask

console.log("global execution");

執行結果如下

global execution
microtask
timeout

  1. 首先要等call stack清空才會去判斷非同步的callback, 所以global execution會首先被印出.
  2. 而根據順序來說應會先去執行一個Macrotask才會跑到Microtask, 目前想過能給的解釋是, 第一次載入JS這個冬作也是一個macrotask, 所以在全域環境堆疊完後, 他會直接執行microtask.
  3. 所以下一個會先檢查Microtask和執行跟清空, 所以microtask會被接著印出. 然後在往跑Loop, 才會印出timeout

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言