Web Worker 通过外部 JS 文件创建,主线程与 Worker 线程隔离,需用 postMessage 通信;Worker 内不可操作 DOM,销毁须调用 terminate 或 close,避免内存泄漏。

JavaScript 中通过 Web Worker 实现多线程,主线程与 Worker 线程完全隔离、不能直接共享内存,需靠 postMessage 通信。创建简单,销毁需主动触发,否则长期驻留内存。
如何创建 Web Worker
Worker 必须从外部 JS 文件启动(不能内联),且受同源策略限制:
- 新建一个独立的 JS 文件(如
worker.js),写入 Worker 的逻辑 - 在主线程中用
new Worker('worker.js')实例化 - 通过
worker.postMessage(data)向 Worker 发送数据 - 用
worker.onmessage或addEventListener('message', ...)接收返回
示例:
// main.js
const worker = new Worker('calc.js');<br>
worker.postMessage({ type: 'start', data: [1, 2, 3, 4] });<br>
worker.onmessage = (e) => console.log('结果:', e.data);
Worker 文件怎么写
Worker 脚本运行在独立上下文,没有 window、document 等 DOM 对象,但可使用 self(等价于全局作用域):
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 监听
self.onmessage或self.addEventListener('message', ...)接收消息 - 用
self.postMessage(result)将结果发回主线程 - 可导入其他脚本:
importScripts('lib.js', 'utils.js') - 支持
fetch、setTimeout、WebAssembly等,但不可操作 DOM
示例:
// calc.js
self.onmessage = function(e) {<br>
if (e.data.type === 'start') {<br>
const sum = e.data.data.reduce((a, b) => a + b, 0);<br>
self.postMessage({ result: sum });<br>
}<br>
};
如何正确销毁 Web Worker
Worker 不会自动销毁,即使任务完成也持续运行,必须显式终止:
立即学习“Java免费学习笔记(深入)”;
- 主线程调用
worker.terminate()—— 立即结束 Worker,无法再通信 - Worker 自己调用
self.close()—— 主动退出,释放资源 - 避免内存泄漏:不再需要时及时
terminate,尤其在单页应用组件卸载时 - 注意:
terminate后无法重用该 Worker 实例,需新建
常见做法:
function cleanup() {<br>
if (worker) {<br>
worker.terminate();<br>
worker = null;<br>
}<br>
}<br>
// 组件卸载或用户离开前调用 cleanup()
注意事项和常见陷阱
Web Worker 强大但有边界,用错容易出问题:
- 传输对象默认是结构化克隆,不是引用传递;若需共享内存,改用
SharedArrayBuffer(需配合Atomics) - Worker 中抛出未捕获错误不会影响主线程,但会导致 Worker 静默终止,建议加
self.onerror监控 - 调试时可在 DevTools 的 Sources → Workers 面板查看和断点调试
- 不支持
localStorage、indexedDB可用但需在 Worker 内打开(indexedDB.open是允许的)

















