Skip to content

Web Worker

概述

Web Worker 允许在后台线程执行 JavaScript,避免阻塞主线程。

一、Worker 类型

类型作用域通信用途
Dedicated Worker单页面postMessageCPU 密集计算
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 只负责计算,返回结果给主线程。

前端面试知识库