JavaScript 事件循環

探索 JavaScript 事件循環

October 10, 2024

什麼是事件循環?

在深入了解事件循環之前,讓我們先回顧一些 JavaScript 中基本但重要的概念。 JavaScript 是一種單執行緒語言,這意味著 JavaScript 一次只能做一件事,它無法同時做多件事。 但有時我們需要同時做多件事,例如當我們發起 API 呼叫時,我們不想等待回應,我們希望繼續執行程式碼,並在回應準備好時處理它。這就是事件循環發揮作用的地方。

JavaScript 執行時期模型

JavaScript 執行時期模型由以下組件組成:

呼叫堆疊 (Call Stack)
堆 (Heap)
佇列 (Queue**)**
事件循環 (Event Loop)

事件循環如何運作?

事件循環是一種使 JavaScript 非阻塞的機制。它允許 JavaScript 執行多個任務而無需等待每個任務完成,可以將它視為任務排程器,將任務排程在未來執行。 本質上,事件循環持續檢查呼叫堆疊是否為空。當呼叫堆疊清空後,它會先將微任務佇列中的所有任務依序移至呼叫堆疊執行——包含執行過程中新增的微任務——直到微任務佇列完全清空為止。接著才從宏任務佇列取出一個任務執行,執行完畢後再次重複上述流程。 讓我們看一張圖表來了解事件循環如何運作,以及它如何處理宏任務。

  1. JavaScript 執行環境開始讀取程式碼,建立全域執行環境,並將其推入呼叫堆疊,在這個階段,可以將 main() 視為正在執行的函式。
  2. 第一行程式碼是 console.log('Start'),這會被推入呼叫堆疊,並立即執行,完成後會從呼叫堆疊中彈出。
  3. 第二行程式碼是 setTimeout(),它也會被推入呼叫堆疊,但隨後會被移至 Web APIs,並註冊一個計時器。
  1. 最後一行程式碼是 console.log('End'),和第一行一樣,它會被推入呼叫堆疊,並立即執行,完成後會從呼叫堆疊中彈出。
  2. 0 秒後,計時器完成,setTimeout() 的回呼函式會被移至宏任務佇列。
  3. 事件循環會檢查呼叫堆疊是否為空,然後檢查宏任務佇列,如果宏任務佇列中有任務,它會將任務移至呼叫堆疊。

這是一個圖表,展示事件循環如何運作,以及它如何處理微任務。

當同時有微任務和宏任務時,事件循環總是先處理微任務,然後再處理宏任務。

結論

回到部落格 🏃🏽‍♀️