5月27日 14:02

How does Web Worker communicate with the main thread?

Communication between Web Worker and the main thread is primarily achieved through the postMessage() method and onmessage event.

Basic Communication Mechanism

Main Thread Sending Messages to Worker

javascript
const worker = new Worker('worker.js'); // Send simple data worker.postMessage('Hello Worker'); // Send complex objects worker.postMessage({ type: 'compute', data: [1, 2, 3, 4, 5] }); // Send Transferable Objects const buffer = new ArrayBuffer(1024); worker.postMessage({ buffer }, [buffer]);

Worker Sending Messages to Main Thread

javascript
// worker.js self.onmessage = function(event) { const result = processData(event.data); self.postMessage(result); }; // Or use addEventListener self.addEventListener('message', function(event) { self.postMessage({ status: 'received' }); });

Message Passing Characteristics

1. Deep Copy vs Transfer

By default, messages are passed through deep copy:

javascript
// Deep copy - original data retained const data = { value: 42 }; worker.postMessage(data); console.log(data.value); // 42 - data still exists

Use Transferable Objects for transfer:

javascript
// Transfer - original data cleared const buffer = new ArrayBuffer(1024); worker.postMessage({ buffer }, [buffer]); console.log(buffer.byteLength); // 0 - data has been transferred

2. Structured Clone Algorithm

postMessage uses the structured clone algorithm, supporting:

  • Basic types (string, number, boolean, null, undefined)
  • Objects and arrays
  • Date, RegExp, Blob, File, ArrayBuffer
  • Map, Set, ImageData

Does not support:

  • Functions
  • DOM nodes
  • Error objects
  • Symbol

Bidirectional Communication Example

javascript
// Main thread const worker = new Worker('worker.js'); worker.onmessage = function(event) { console.log('Worker says:', event.data); }; worker.postMessage({ action: 'start' }); // worker.js self.onmessage = function(event) { if (event.data.action === 'start') { // Execute task const result = heavyComputation(); self.postMessage({ action: 'complete', result }); } };

Message Queue

Messages are asynchronous and passed through a message queue:

javascript
// Main thread sends multiple messages consecutively for (let i = 0; i < 5; i++) { worker.postMessage({ index: i }); } // Worker receives in order self.onmessage = function(event) { console.log('Processing:', event.data.index); };

Error Handling

javascript
// Main thread listens for Worker errors worker.onerror = function(event) { console.error('Worker error:', event.message); console.error('Filename:', event.filename); console.error('Line:', event.lineno); }; // Internal error handling in Worker try { // Code that might error } catch (error) { self.postMessage({ error: error.message }); }

Performance Optimization Recommendations

  1. Use Transferable Objects: For large data (ArrayBuffer, Blob), use transfer instead of copy
  2. Batch Processing: Reduce message passing frequency, merge data
  3. Avoid Frequent Communication: Try to complete more calculations within the Worker
  4. Use SharedArrayBuffer: Multiple Workers share memory (requires specific header configuration)
标签:Web Worker