HTML5 Web Workers 多线程
Web Workers 是 HTML5 提供的多线程解决方案,允许在后台线程中执行 JavaScript 代码,避免阻塞主线程。
简介
JavaScript 通常在单线程环境中执行,这意味着耗时的操作(如大量数据处理、复杂计算)会阻塞用户界面,导致页面卡顿。Web Workers 的出现解决了这个问题,它允许创建多个后台线程,在独立的环境中执行脚本,互不阻塞。
Web Workers 适用于处理复杂计算、数据处理、图像处理、文件解析等耗时任务。
创建 Web Worker
通过 Worker 构造函数创建新的 Web Worker,需要指定 Worker 脚本的 URL:
创建 Worker
// 主线程创建 Worker
var worker = new Worker("worker.js");
// 也可以创建 Blob URL 的 Worker
var blob = new Blob(["self.onmessage = function(e) {" +
" self.postMessage('Hello from worker!');" +
"}"], {type: "text/javascript"});
var worker = new Worker(URL.createObjectURL(blob));
消息通信
主线程与 Worker 之间通过 postMessage 方法发送消息,通过 onmessage 事件接收消息:
消息通信示例
// 主线程代码
var worker = new Worker("worker.js");
// 发送消息给 Worker
worker.postMessage({type: "compute", data: [1, 2, 3, 4, 5]});
// 接收 Worker 返回的消息
worker.onmessage = function(event) {
console.log("结果: " + event.data);
};
// 处理 Worker 错误
worker.onerror = function(error) {
console.error("Worker 错误: " + error.message);
};
Worker 内部代码 (worker.js)
// Worker 内部代码
self.onmessage = function(event) {
var data = event.data;
if (data.type === "compute") {
// 执行计算
var result = data.data.reduce(function(a, b) {
return a + b;
}, 0);
// 返回结果给主线程
self.postMessage(result);
}
};
// 也可以使用 this 引用
// this.onmessage = function(event) { ... }
终止 Worker
当 Worker 不再需要时,应该及时终止以释放资源:
终止 Worker
// 主线程终止 Worker
worker.terminate();
// Worker 内部自我终止
// self.close();
导入脚本
Worker 可以使用 importScripts 方法导入其他 JavaScript 文件:
导入脚本
// Worker 内部导入其他脚本
// importScripts("utility1.js");
// importScripts("utility2.js", "utility3.js");
限制与注意事项
Worker 限制
- Worker 无法访问 DOM(不能操作页面元素)
- Worker 无法访问全局变量和函数
- Worker 无法使用 window 对象的多数属性
- Worker 可以使用 self(全局作用域)和 location 对象
- Worker 之间不能直接通信(需通过主线程转发)