MessageChannel

Lesson 2 · ~8 minutes · still no iframe

Start the queue, close the pipe

A port is a mailbox that starts shut. Posts wait. onmessage opens it. addEventListener does not, until start(). close() cuts the pair.

port.postMessage(data) has no targetOrigin. The payload is structured-cloned onto the other port’s port message queue. That queue is born disabled: tasks sit there so they are not dropped before you attach a handler. The first time you set onmessage, the spec enables the queue as if you had called start(). addEventListener("message", …) does not. (HTML §9.4.1.1, MDN start())

port.addEventListener("message", onMsg);
port.start();                 // required

port.onmessage = onMsg;       // start() implied

Once enabled, a queue is never disabled again. close() is not a pause: it disentangles the pair. Later posts find no twin and return without delivering. Call close() yourself so the ports can be collected; do not wait for GC. (HTML §9.4.4, §9.4.5, MDN close())

Feel the queue

This lab uses a real MessageChannel. The listener is wired with addEventListener only — no implied start. Post, then start, then post live, then close and post again. Same-page use is still a teaching trick.

The lab needs JavaScript in this page.

Check

You listen with addEventListener("message") and never call start(). Something is posted to this port. What happens?

You set port.onmessage = handler. What about start()?

Why is the port message queue born disabled?

After start(), can you pause that queue?

port1.close(), then port2.postMessage("hi"). What happens to that post?

Which window.postMessage argument does port.postMessage not take?

Primary source

Read the contacts-provider snippet and the paragraph under it: HTML Living Standard §9.4.1.1 Examples. That is the addEventListener vs onmessage / start() rule in one place. Then skim start() and close() in §9.4.4 Message ports.

Ask the teacher

If the silent-listener gotcha is still mushy — especially “I used addEventListener and nothing arrived” — ask. Next: moving a port (transfer list, event.ports, detach, DataCloneError). Pocket cards: entangled ports, port API.