Web Workers允许JavaScript在后台线程运行而不阻塞主线程,需通过外部同源JS文件创建,拥有独立执行环境(无DOM、localStorage等),通信仅依赖postMessage/onmessage异步消息传递,支持结构化克隆与ArrayBuffer转移,可调用worker.terminate()或self.close()终止,常见类型为Dedicated Worker(一对一)和Shared Worker(多页面共享)。

Web Workers 让 JavaScript 能在后台线程中运行脚本,不阻塞主线程(比如页面渲染、用户交互)。实现它不难,关键在于理解“独立执行环境”和“基于消息的通信”这两个核心点。
如何创建并启动一个 Web Worker
Worker 必须从外部 JS 文件加载(不能是内联脚本),且同源。浏览器会为它分配独立的全局上下文(self 代替 window),没有 DOM、document 或 localStorage 等 API。
- 新建一个文件,例如
worker.js,写入要后台执行的逻辑:
self.onmessage = function(e) {
const result = e.data * 2;
self.postMessage(result);
};
- 在主页面中创建 Worker 实例并发送消息:
const worker = new Worker('worker.js');
worker.postMessage(42); // 发送数字 42
worker.onmessage = function(e) {
console.log('收到结果:', e.data); // 输出 84
};
主线程与 Worker 之间如何通信
通信只能通过 postMessage() 和 onmessage 进行,**是异步、事件驱动、纯消息传递**,不共享内存。所有数据都会被结构化克隆(structured clone),意味着大多数基本类型、数组、对象、Map、Set 等可传,但函数、DOM 节点、undefined、Symbol 等不行。
- 发送消息用
worker.postMessage(data)或self.postMessage(data) - 监听消息统一用
onmessage = function(e) { ... },其中e.data是传来的数据 - 支持传输 ArrayBuffer 等可转移对象(transferable),大幅提升大数据量处理效率(如图像、音频):
// 主线程中发送并转移 ArrayBuffer
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]); // 第二个参数表示转移所有权
注意:一旦转移,原上下文不能再访问该 buffer。
立即学习“Java免费学习笔记(深入)”;
如何终止 Worker
避免内存泄漏或无用运行,记得及时关闭。
- 主线程调用
worker.terminate()—— 立即停止,不触发 Worker 内部清理逻辑 - Worker 自己调用
self.close()—— 安全退出,适合完成任务后主动结束
Worker 结束后,其引用可被 GC 回收;但未 terminate 的 Worker 仍驻留内存,即使页面隐藏。
常见类型:Dedicated Worker vs Shared Worker
日常用的是 Dedicated Worker(一对一),每个实例只与创建它的脚本通信。Shared Worker 则允许多个页面/脚本共用一个 Worker(需同源),通过 port 通信:
- Shared Worker 构造时需指定 name:
new SharedWorker('shared.js', 'myWorker') - 必须显式调用
port.start()启动消息通道 - 适合跨 iframe 或多标签页共享状态或轮询逻辑(如统一通知服务)
不过多数场景用 Dedicated 就够了,更简单、更可控。
基本上就这些。Web Workers 不复杂但容易忽略通信边界和生命周期管理 —— 记住:没共享内存、没 DOM、靠消息、记得关。











