跳转到主内容
极星编程网:以代码为星,赴技术山海!

Web Workers如何实现javascript多线程【教程】

Web Workers 并非真正多线程,而是内存隔离的独立线程,需通过 URL 实例化(如 Blob URL 或文件路径),仅支持结构化克隆通信,不可传函数/DOM/RegExp等,无 window/document API,须手动错误监听与 terminate 清理。 Web Workers 不能真正实现 JavaScript 多线程——JS 主线程本身仍是单线程的,Workers 只是把脚本挪到独立的、与主线程**内存隔离**的线程里运行,不共享变量,靠
postMessage
通信。 Worker 实例化必须用 URL,不能直接传函数或字符串 很多人想这么写:
new Worker(() => { console.log('hi') })
或
new Worker('console.log(1)')
,这会直接报错
SyntaxError: Failed to construct 'Worker': Script URL must be of scheme http, https, or blob
。 必须提供一个可加载的脚本 URL: 推荐用
Blob URL
动态创建(避免额外文件):
const code = `self.onmessage = () => self.postMessage('done')`; const blob = new Blob([code], { type: 'application/javascript' }); const worker = new Worker(URL.createObjectURL(blob));
或单独写个
worker.js
文件,用
new Worker('./worker.js')
Vite/webpack 环境下注意:
import.meta.url
和相对路径解析行为不同,建议统一用
new URL('./worker.js', import.meta.url)
构造 URL 主线程和 Worker 之间只能传可序列化的值,不能传函数、DOM 节点、Promise
postMessage
底层走的是结构化克隆算法(structured clone),不支持函数、
undefined
、
Symbol
、
RegExp
、
Error
、
Map
/
Set
(部分环境)、以及任何带原型链的对象。 立即学习 “ Java免费学习笔记(深入) ”; Trae win Trae Windows 官方版本现已全面支持 Win10 和 Win11 系统(64位)。国内开发者可直接访问 Trae 中文官网(trae.cn 或 trae.com.cn),一键下载官方正版 .exe 安装包,享受国内直连的高速稳定体验。安装过程极其简便,双击即可运行,并支持一键无缝导入 VS Code 或 Cursor 的原有主题、快捷键及插件配置。登录支持手机号、微信或稀土掘金账号。内置免费的豆包与 DeepSeek 等顶级大模型,让你开箱即用,轻松开启高效的 AI 智能编程之旅。 下载 常见翻车点: 传了
{ data, callback }
想让 Worker 回调?不行,
callback
会被静默丢弃 传了
document.getElementById('x')
?直接抛
DataCloneError
想传大数组或 TypedArray?可以,但默认会拷贝——如需零拷贝,得用
transferable
参数:
worker.postMessage(arr, [arr.buffer])
Worker 内不能访问 win dow、document、localStorage 等主线程专属 API Worker 运行在独立上下文,全局对象是
self
(不是
window
),没有 DOM、没有 BOM、不能发同步 XHR、不能用
alert
。能用的有:
setTimeout
/
setInterval
fetch
(现代 Worker 支持,但注意 CORS)
atob
/
btoa
、
JSON
、
TextEncoder
/
TextDecoder
importScripts()
(加载其他 JS,但不支持 ES module 语法,除非用
import
+
type="module"
声明)
self.postMessage
、
self.onmessage
、
self.close()
如果需要操作 canvas 或音频,得靠主线程传数据回来再渲染;Worker 只负责计算密集型任务,比如解析大 JSON、加密解密、图像像素处理。 真正容易被忽略的不是怎么启 Worker,而是错误捕获和生命周期管理:Worker 抛错不会冒泡到主线程,
onerror
必须显式监听;长期运行的 Worker 如果没关,会持续占内存;用完记得调
worker.terminate()
,别只靠用户关页面来回收。

相关文章