javascript如何实现web workers_它们如何通信

15次阅读

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

javascript如何实现web workers_它们如何通信

Web Workers 让 javascript 能在后台线程中运行脚本,不阻塞主线程(比如页面渲染、用户交互)。实现它不难,关键在于理解“独立执行环境”和“基于消息的通信”这两个核心点。

如何创建并启动一个 Web Worker

Worker 必须从外部 JS 文件加载(不能是内联脚本),且同源。浏览器会为它分配独立的全局上下文(self 代替 window),没有 DOM、documentlocalStorage 等 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 节点、undefinedsymbol 等不行。

  • 发送消息用 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、靠消息、记得关。

text=ZqhQzanResources