Web Workers 提供隔离的消息传递式并行,不支持共享内存;必须通过独立JS文件创建,禁止访问DOM、window等;通信依赖postMessage结构化克隆,大数据需用Transferable零拷贝;错误默认静默,须主动监听error事件。

Web Workers 不能真正实现“多线程”意义上的共享内存并发,它提供的是**隔离的、消息传递式的并行执行环境**。直接操作 DOM、访问 window 或 document 会报错,这是设计使然,不是 bug。
如何创建并启动一个 Dedicated Worker
必须把 Worker 逻辑写在**独立的 JS 文件中**,不能内联字符串(除非用 Blob,但不推荐)。
-
new Worker('path/to/worker.js')是唯一标准方式;new Worker('data:text/javascript,...')或内联函数会触发安全限制(如 Chrome 的SecurityError: Failed to construct 'Worker') - 主线程与 Worker 之间只能通过
postMessage()和onmessage通信,数据会被结构化克隆(即深拷贝),引用关系丢失 - Worker 文件路径需满足同源策略,本地文件协议(
file://)下多数浏览器直接拒绝加载
Worker 文件里不能写什么?
Worker 全局作用域是 WorkerGlobalScope,没有 DOM API,也没有部分浏览器专属对象。
- 禁止使用:
document、window、localStorage、fetch(注意:现代浏览器已支持fetch,但 IE 不支持)、console.log(可用,但输出在 DevTools 的 “Workers” 标签页,容易被忽略) - 可用但行为不同:
setTimeout/setInterval可用,但this指向self,不是window - 必须显式监听:
self.onmessage = function(e) { ... }或self.addEventListener('message', ...),否则收不到主线程消息
怎样传复杂数据(如 ArrayBuffer 或 Transferable)?
默认 postMessage() 会拷贝整个对象,大数据量(如图像像素、大型数组)时性能极差。用 Transferable 可零拷贝移交控制权,但移交后原线程不能再访问该对象。
立即学习“Java免费学习笔记(深入)”;
- 只支持特定类型:
ArrayBuffer、MessagePort、ImageBitmap(部分浏览器)、OffscreenCanvas - 语法必须带第二个参数:
worker.postMessage(data, [data.buffer])—— 注意是buffer属性,不是整个 TypedArray - 移交后主线程的
array.buffer变为detached,再读取会抛TypeError: array buffer is detached
/* 主线程 */
const arr = new Uint8Array([1,2,3,4]);
const worker = new Worker('compute.js');
worker.postMessage(arr, [arr.buffer]); // ✅ 零拷贝移交
/ compute.js /
self.onmessage = function(e) {
const arr = new Uint8Array(e.data); // ✅ 接收后可直接用
// arr.buffer 现在属于 Worker,主线程的已 detached
};
常见错误:Worker 报错却看不到堆栈
Worker 内部抛出未捕获异常,默认不会中断主线程,也不会在主控制台显示错误 —— 它静默失败,除非你主动监听 error 事件。
- 主线程监听:
worker.onerror = e => console.error('Worker error:', e.message) - Worker 内监听:
self.onerror = e => console.error('Inside worker:', e.message) - 调试建议:在 Worker 开头加
self.console.log('worker started'),确认是否加载成功 - 路径错误时,Chrome 显示
Failed to load resource: net::ERR_FILE_NOT_FOUND,但不提示是哪个 Worker
真正难处理的从来不是怎么启一个 Worker,而是如何设计消息粒度、避免频繁序列化、判断何时该用 SharedArrayBuffer(需 HTTPS + cross-origin isolation)而不是普通 Worker —— 这些没写清楚,光跑通 demo 没用。











