Suggest an editImprove this articleRefine the answer for “What does postMessage() do between threads?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`postMessage()`** is a method that lets you send a message from one context to another (for example, from the main thread to a Web Worker or vice versa). **Key point:** it does not access memory directly; it passes a copy of the data asynchronously through the message-passing mechanism.Shown above the full answer for quick recall.Answer (EN)Image## What `postMessage()` does > `postMessage()` is a method that lets you **send a message from one context to another** > (for example, from the main thread to a Web Worker or vice versa). It **does not perform direct memory access**, but passes a **copy** of the data, asynchronously, through the **message passing** mechanism. ## What this looks like with a Web Worker ### Example ```javascript // main.js const worker = new Worker('worker.js'); // Send a message to the worker worker.postMessage({ task: 'sum', a: 5, b: 7 }); // Get the response worker.onmessage = (event) => { console.log('Response from the worker:', event.data); }; ``` ```javascript // worker.js onmessage = (event) => { const { task, a, b } = event.data; if (task === 'sum') { postMessage(a + b); // send the result back } }; ``` **What happens:** 1. The main thread calls `worker.postMessage(...)`; 2. The message is serialized and placed into the worker's **message queue**; 3. The `onmessage` event fires in the worker; 4. The worker processes it and replies via `postMessage()`; 5. The main thread catches that event via `onmessage`. All of this happens **asynchronously**; JavaScript **does not wait** for the worker to respond. ## What exactly gets passed You can pass: - Primitives (`string`, `number`, `boolean`, `null`, `undefined`); - Objects (JSON-compatible); - `ArrayBuffer`, `Blob`, `File`, `ImageBitmap`; - **Transferable objects** - passed **without copying**. ## What Transferable Objects are Normally data **is copied** when passed between threads (via structured clone). But for large binary data this is expensive. > **Transferable objects** (for example, `ArrayBuffer`) can be "passed by reference" > - without copying, just by **transferring ownership**. ### Example: ```javascript const buffer = new ArrayBuffer(1024); worker.postMessage(buffer, [buffer]); // pass it as transferable ``` After transfer, `buffer` becomes **invalid** in the main thread (because "ownership" has moved to the worker). This is **10-100 times faster** when transferring large data. ## What `postMessage()` returns Nothing. It simply queues a message on the other side. The receiver catches it through the `message` event: ```javascript worker.onmessage = (event) => { console.log(event.data); }; ``` ## Communication in both directions | From | Method | Listener | |---|---|---| | Main thread -> worker | `worker.postMessage()` | `onmessage` in the worker | | Worker -> main thread | `postMessage()` | `worker.onmessage` | ## An "echo" example (echo worker) ```javascript // worker.js onmessage = (event) => { postMessage(`Echo: ${event.data}`); }; ``` ```javascript // main.js worker.postMessage('Hello!'); worker.onmessage = (e) => console.log(e.data); // -> "Echo: Hello!" ``` ## `postMessage()` is not only for Web Workers This method is universal; it works across different browser contexts: | Where it is used | Example | |---|---| | **window -> iframe** | `iframe.contentWindow.postMessage(data, origin)` | | **iframe -> parent** | `window.parent.postMessage(data, origin)` | | **between tabs** | `otherWindow.postMessage(data, origin)` | | **Service Worker <-> Main** | `navigator.serviceWorker.controller.postMessage(data)` | | **Web Worker <-> Main** | `worker.postMessage(data)` | ## Example: `window.postMessage()` between pages ```javascript // Page A const popup = window.open('https://example.com/popup.html'); popup.postMessage('Hi, page B!', 'https://example.com'); // Page B window.addEventListener('message', (event) => { if (event.origin === 'https://example.com') { console.log('Message received:', event.data); } }); ``` Very useful for **safe communication** between different domains (CORS-safe). ## How it works under the hood 1. When `postMessage()` is called, the data **is serialized** using the Structured Clone Algorithm; 2. A copy of the data is placed into the receiver's queue; 3. When the thread frees up, the browser calls the `onmessage(event)` handler; 4. The data is available in `event.data`. ## What is inside `event` ```javascript onmessage = (event) => { console.log(event.data); // the data itself console.log(event.origin); // the source (for windows/iframes) console.log(event.ports); // MessagePort, if any console.log(event.source); // who sent the message }; ``` ## A simple analogy Think of `postMessage()` as **a postal service between offices**. Each office (a JS thread) works **in isolation**. When one wants to pass data to another, it drops a letter (a message) into a mailbox (`postMessage`). The other office picks up the letter when it has time (`onmessage`). ## Summary | What it does | Explanation | |---|---| | `postMessage()` | Sends a message between threads / contexts | | **Works asynchronously** | Does not block the code | | **Passes data by copy** | Through structured clone | | **Optimization** | Transferable objects - without copying | | **Two-way communication** | Both threads can send and receive | | **Used where** | Web Workers, iframes, windows, Service Workers |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.