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