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
javascriptconst 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
- Use Transferable Objects: For large data (ArrayBuffer, Blob), use transfer instead of copy
- Batch Processing: Reduce message passing frequency, merge data
- Avoid Frequent Communication: Try to complete more calculations within the Worker
- Use SharedArrayBuffer: Multiple Workers share memory (requires specific header configuration)