Web Worker 如何实现多线程?与主线程如何通信?
请说明 Web Worker 的创建、通信方式(postMessage/onmessage)、终止以及使用限制。
回答
孤独的心
Web Worker:浏览器提供的后台线程,可执行耗时任务而不阻塞 UI。
创建 Worker:
// worker.js
self.onmessage = function(e) {
const result = heavyComputation(e.data);
self.postMessage(result);
};
function heavyComputation(data) {
// 耗时计算…
return data.map(x => x * 2);
}
// main.js
const worker = new Worker('worker.js');
worker.postMessage([1, 2, 3, 4, 5]);
worker.onmessage = (e) => {
console.log('Worker 返回:', e.data);
};
worker.onerror = (e) => {
console.error('Worker 错误:', e.message);
};
// 终止 Worker
worker.terminate();
通信:
- 主线程 → Worker:
worker.postMessage(data) - Worker → 主线程:
self.postMessage(data) - 数据通过结构化克隆(structured clone)传递,不是共享引用
- 支持 Transferable Objects(如 ArrayBuffer)零拷贝传输
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]); // buffer 所有权转移
限制:
- 不能直接操作 DOM、BOM(window/document)
- 不能访问
parent、localStorage、sessionStorage - 可访问
XMLHttpRequest、fetch、indexedDB、navigator、setTimeout等
子类型:
- SharedWorker:多个页面共享一个 Worker
- Service Worker:网络代理(离线/缓存/推送)