Page 3
var worker = new Worker('./worker.js');That one line does everything:
- Browser fetches
worker.jsfrom the server - Spins up a new thread
- Starts running that file on it
The Only Thing You Need to Get Right — The Path
new Worker('./worker.js') // same folder as current page
new Worker('/js/worker.js') // absolute path from server root
new Worker('../workers/fib.js') // relative path going up a folderSame rules as any fetch() or <script src="...">. Just point it at the right file.
What You Get Back
The new Worker() call immediately returns a worker object — your handle to communicate with that thread:
var worker = new Worker('./worker.js');
worker.postMessage(...) // send data TO the worker
worker.addEventListener('message') // receive data FROM the worker
worker.terminate() // kill the threadThat's the entire API for talking to a worker. Three things. That's it.
No, postMessage does not close the thread. It just sends data — the thread stays alive after.
var start = Date.now();
var answer = fib(42); // 1. calculate
var ms = Date.now() - start;
self.postMessage({ answer, ms }); // 2. send result — thread still running
// 3. nothing left to do, so it goes idleThe thread closes because the script ran out of code to execute — not because of postMessage.
The Difference
// worker.js — sends one message then goes idle (nothing left to run)
self.postMessage('done');
// ↑ thread is now idle but technically still alive until terminate()
// worker.js — sends many messages, stays busy
function next() {
self.postMessage(fib(n++));
setTimeout(next, 0); // keeps scheduling more work → stays alive
}
next();Three Ways a Worker Actually Closes
// 1. From the PAGE — forceful, immediate
worker.terminate();
// 2. From INSIDE the worker — graceful self-close
self.close();
// 3. Naturally — worker script finishes and has no pending timers/listeners
// browser garbage collects it eventuallyIn example 02, after self.postMessage(...) there's no more code, no setTimeout, no event listeners — so the worker goes idle naturally. But in example 03, setTimeout(next, 0) keeps scheduling more work, which is why you need terminate() to stop it.
Two sides of the same communication channel — direction is the only difference:
PAGE (main.js) WORKER (worker.js)
─────────────────────────────────────────────────────
worker.postMessage() ───► self.addEventListener('message')
worker.addEventListener('message') ◄─── self.postMessage()worker.postMessage() — Page talks TO the worker
// main.js — you have the worker object, so you use it
worker.postMessage({ stop: true });self.postMessage() — Worker talks TO the page
// worker.js — you don't have a "page" object, so you use self
self.postMessage({ n: 42, result: 999 });The reason for self
Inside a worker there is no window, no document, no reference to the page. The only thing the worker knows about itself is self. So:
// main.js → has window, document, worker object
// worker.js → has only selfself in a worker is exactly like window in a page — it's the global scope of that thread.
Symmetric Pattern
// main.js
worker.postMessage('ping');
worker.addEventListener('message', evt => console.log(evt.data)); // receives 'pong'
// worker.js
self.addEventListener('message', evt => {
if (evt.data === 'ping') self.postMessage('pong');
});Same postMessage + addEventListener('message') on both sides — just different objects (worker vs self).
Yes, exactly. terminate() doesn't wait in any queue — it's an outside kill, not a message.
worker.postMessage({ stop: true }) → goes into the message QUEUE
worker reads it when it's free
worker.terminate() → bypasses everything
thread dies RIGHT NOWWhy the Priority Difference Exists
postMessage is cooperative — it asks the worker to stop itself. The worker has to:
- Finish current calculation
- Return to event loop
- Read the queue
- See the stop message
- Call
self.close()
terminate() is forceful — the browser kills the OS thread directly. No cooperation needed, no queue checked, no code runs.
// This can be ignored if worker is busy:
worker.postMessage({ stop: true }); // "please stop when you get a chance"
// This cannot be ignored, ever:
worker.terminate(); // "you are dead right now"The Analogy
Think of it like a running program:
postMessage({ stop: true }) = asking someone nicely to stop working
terminate() = pulling the power cable out of the computerOne depends on the other person cooperating. The other doesn't ask.