De-yu's Note
  • Deyu Notebook
  • Side Project
    • Stock
    • ChatBox
    • SnowCraft
    • ScrollBar
  • 架構問題
    • 解決 RTK Query data 為 undefined 的實務做法
    • 透過 xstate 解決UI 狀態問題
  • 技術觀點
    • 為什麼需要 store
    • Router 作用
    • react 和 next.js 差異
    • monoRepo vs Multiple Repo
  • Performance
    • React 優化
  • JS Coding
    • Curry
    • Debounce
    • Throttle
  • map
  • memo()
  • Promise 實作
  • Promise Function
  • Testing
    • 使用 Jest 、 React Testing Library 、MSW 建立測試環境
  • Miscellaneous
    • Event Loop
    • Browser
    • Code Review
    • Storage
  • AMD 、 CommonJS 、 ES modules
  • JWT
  • Next.js
  • 用過的 module
  • Internet
    • UDP
  • TCP/IP
  • SSL TLS
  • HTTP
  • AI 工作流
    • Page 1
Powered by GitBook
On this page
  1. Miscellaneous

Event Loop

Event Loop 可以理解為整個 JavaScript 程式運行的核心機制。 因為 JavaScript 是**單執行緒(single-threaded)的語言,它同一時間只能做一件事。為了能有效處理大量操作(例如等待 API 回應、計時器、DOM 事件等),就必須透過非同步機制(asynchronous mechanism)**來執行程式碼,避免程式被「阻塞(block)」。

JavaScript 運行時的主要組件

  • Heap: 記憶體區域,用來儲存**物件(Object)**等大型資料。

  • Call Stack(呼叫堆疊): 負責記錄目前正在執行的函數。 採用**後進先出(LIFO, Last In First Out)**的結構:

    • 當函數被呼叫時,會被**推入(push)**堆疊。

    • 當函數執行完畢,會從堆疊彈出(pop)。

  • Task Queues(任務隊列): 當某些非同步操作完成時,對應的回呼函數(callback)會被排進這些隊列中,等待 Call Stack 清空後進入執行。

    • Macro Task Queue(巨集任務隊列) 例如:setTimeout、setInterval、setImmediate、Web API callback 等。

    • Micro Task Queue(微任務隊列) 例如:Promise.then/catch/finally、MutationObserver。 Microtasks 的優先度比 Macrotasks 更高。


運作流程(Event Loop 如何工作)

  1. 當程式開始執行時,同步程式碼會直接進入 Call Stack。

  2. 非同步操作(如 setTimeout、fetch 等)會交給瀏覽器的 Web APIs,當這些操作完成後,對應的 callback 會被推到適當的 Task Queue 中。

  3. Event Loop 會不斷檢查:

    • 當 Call Stack 為空時,會先從 Microtask Queue 拿任務執行。

    • Microtasks 全部清完後,才從 Macrotask Queue 拿下一個任務執行。

  4. 不斷重複以上步驟,直到所有任務都處理完畢。


補充:同步 vs 非同步

  • 同步:一件事情做完,才能做下一件事。會直接在 Call Stack 中排隊,容易阻塞。

  • 非同步:把事情交給外部處理(像是瀏覽器的 Web API),程式可以繼續做其他事,不會被卡住。

一個超簡單的小範例:

console.log('start');

setTimeout(() => {
  console.log('timeout');
}, 0);

Promise.resolve().then(() => {
  console.log('promise');
});

console.log('end');

輸出順序會是:

start
end
promise
timeout

解釋:

  • start 和 end 是同步程式,直接進 Call Stack。

  • Promise.then 是 Microtask,會排在同步之後馬上執行。

  • setTimeout 是 Macrotask,即便時間設 0,還是要等到 Microtask 都清完後才執行。

Previous使用 Jest 、 React Testing Library 、MSW 建立測試環境NextBrowser

Last updated 20 days ago