什么是Web Workers_JavaScript中如何创建多线程

12次阅读

Web Workers 提供后台线程运行脚本的机制,主线程与 Worker 线程隔离,仅通过 postMessage 通信;必须加载外部 js 文件,不可内联;Worker 中无法操作 dom 或访问 window、document 等对象

什么是Web Workers_JavaScript中如何创建多线程

javaScript 本身是单线程的,Web Workers 不是“让 JS 变成多线程”,而是提供一种**在后台线程运行脚本**的机制,主线程和 Worker 线程彼此隔离、通过消息通信 —— 这是关键前提,否则容易误以为能直接共享变量或 DOM。

Worker 创建必须用外部 JS 文件(不能内联)

浏览器强制要求 Worker 构造函数接收一个 外部 javascript 文件路径,不支持字符串或内联函数。这是安全限制,也是常见报错源头:

const worker = new Worker('worker.js'); // ✅ 正确
const worker = new Worker('data:text/javascript,console.log("hi")'); // ❌ 大部分浏览器拒绝
const worker = new Worker(function() { console.log('no'); }); // ❌ 语法错误

如果你用构建工具(如 vitewebpack),可用 new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }) 来支持模块语法,但本质仍是加载一个独立文件。

postMessage 是唯一通信方式,且只能传可序列化数据

主线程和 Worker 之间无法访问对方作用域,所有交互必须靠 postMessage + onmessage。注意:

立即学习Java免费学习笔记(深入)”;

  • postMessage 第一个参数会被结构化克隆(structured clone),functionundefinedsymbolpromiseDOM 节点 都无法传递
  • 如果要传大数组或二进制数据,用 Transferable(如 ArrayBuffer)避免拷贝:
    worker.postMessage(arrayBuffer, [arrayBuffer]);
  • Worker 内部用 self.postMessage 发送,监听用 self.onmessage,不是 window 对象

Worker 中不能操作 DOM、documentwindow

这是最常被忽略的边界。Worker 运行在完全独立的上下文,没有 documentwindowlocalStoragealert,甚至没有 setTimeout 的完整语义(只有 self.setTimeout,但不可靠)。典型误用:

// 在 worker.js 中 ❌ document.body.innerhtml = 'loading...'; // TypeError: document is not defined console.log(window.location); // ReferenceError: window is not defined

Worker 适合做的事包括:json.parse 大文本、加密/解密、图像像素计算、复杂数学运算、离线缓存预处理 —— 所有不依赖 ui 的纯计算任务。

真正难的不是创建 Worker,而是设计好主线程与 Worker 的消息协议、错误回传机制、以及如何优雅终止(worker.terminate()self.close())。很多性能问题其实源于频繁创建/销毁 Worker,而不是计算本身。

text=ZqhQzanResources