首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 單線程非阻塞機制:Event Loop、Web Workers、setTimeout/Interval 實戰解析

     編輯:程式設計綜合問答

疑問:JS 單線程,若 `setInterval` 每秒更新時間,同時發起耗時 1 秒以上的 `fetch`,時間顯示會不會卡住?

答案:不會卡住,因為 Event Loop 機制

  1. Call Stack:同步代碼入棧執行。
  2. Web APIs:`setTimeout`、`fetch`、`DOM 事件` 由瀏覽器多線程處理,完成後將**回調函數**推入 **Task Queue (Macro-task)** 或 **Micro-task Queue**。
  3. Event Loop:Call Stack 清空 → 執行 Micro-task (Promise/.then) → 取一個 Macro-task 執行 → 渲染 → 循環。

`setInterval` 回調與 `fetch` 回調都是獨立 Macro-task,**互不阻塞**,交替執行。即使 `fetch` 耗時 2 秒,時間顯示仍每秒準時更新 (誤差 ±幾毫秒)。

真正的多線程:Web Workers

  • 適用:大量計算 (圖像處理、加密、解析巨大 JSON) 阻塞主線程導致 UI 卡頓。
  • 用法:
// main.js
const worker = new Worker('heavy.js');
worker.postMessage({data: hugeArray});
worker.onmessage = e => console.log('結果:', e.data);

// heavy.js
self.onmessage = e => {
  const result = heavyComputation(e.data.data);
  self.postMessage(result);
};
  • Worker 有獨立 Event Loop、記憶體空間,**無法直接操作 DOM**,透過 `postMessage` 通訊 (結構化複製/Transferable)。

避坑指南

  • `setInterval` 若回調執行時間 > 間隔,會堆積任務導致延遲;改用 `setTimeout` 遞歸或 `requestAnimationFrame`。
  • 長耗時同步迴圈 (如 `while(true)`) **會徹底凍結頁面**,必須移入 Worker 或拆分為 `setTimeout` 批次。
  • `async/await` 本質仍是 Promise + Micro-task,**不改變單線程本質**,只讓非同步代碼寫起來像同步。

結論:**JS 單線程 ≠ 阻塞**。善用 Event Loop 特性 + Web Workers,輕鬆實現高並發非阻塞應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved