乐闻世界logo
搜索文章和话题

How does Web Worker communicate with the main thread?

2月21日 15:12

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