Web Worker
概述
Web Worker 允许在后台线程执行 JavaScript,避免阻塞主线程。
一、Worker 类型
| 类型 | 作用域 | 通信 | 用途 |
|---|---|---|---|
| Dedicated Worker | 单页面 | postMessage | CPU 密集计算 |
| Shared Worker | 多标签页 | MessagePort | 跨页面共享 |
| Service Worker | 离线缓存 | 事件驱动 | PWA |
二、Dedicated Worker
javascript
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ type: 'compute', data: [1, 2, 3] });
worker.onmessage = (e) => {
console.log('Result:', e.data);
};
worker.onerror = (e) => {
console.error(e.message);
};
worker.terminate(); // 终止
// worker.js
self.onmessage = (e) => {
const { type, data } = e.data;
if (type === 'compute') {
const result = heavyComputation(data);
self.postMessage(result);
}
};传输数据
javascript
// 结构化克隆 (默认,复制)
worker.postMessage({ data: largeArray });
// Transferable Objects (转移所有权,零拷贝)
const buffer = new ArrayBuffer(1024 * 1024);
worker.postMessage(buffer, [buffer]);
// 主线程的 buffer 不再可用三、Shared Worker
javascript
// main.js (多个页面共用)
const worker = new SharedWorker('shared-worker.js');
worker.port.start();
worker.port.postMessage('hello');
worker.port.onmessage = (e) => console.log(e.data);
// shared-worker.js
const connections = [];
self.onconnect = (e) => {
const port = e.ports[0];
connections.push(port);
port.onmessage = (e) => {
connections.forEach(p => p.postMessage('broadcast: ' + e.data));
};
port.start();
};四、使用场景
javascript
// 1. 大数据处理
worker.postMessage({ type: 'parse', csv: largeCsvString });
// 2. 加密计算
worker.postMessage({ type: 'encrypt', data, key });
// 3. 图像处理
worker.postMessage({ type: 'filter', imageData }, [imageData.data.buffer]);
// 4. WebAssembly 执行五、限制
- 无法访问 DOM
- 无法访问 window、document
- 同源限制
- 有限的 API (fetch, IndexedDB, WebSocket 可用)
面试高频题
Q1: Worker 和主线程如何通信?
通过 postMessage 发送,onmessage 接收,数据默认结构化克隆。
Q2: Transferable Objects 是什么?
零拷贝传输,所有权转移,适合大型 ArrayBuffer。
Q3: Worker 访问 DOM 的变通方案?
主线程操作 DOM,Worker 只负责计算,返回结果给主线程。