Start · Sprachen · JavaScript · Referenz · MessagePort.start()

MessagePort.start()

Methode

Startet die Zustellung der Nachrichten, die sich in der Warteschlange eines <code>MessagePort</code> angesammelt haben.

seit JavaScript Baseline: alle Browser (Web Workers, Node.js 10.5+ Kategorie: webapi

Signatur

MessagePort.prototype.start()

Beschreibung

Ein MessagePort ist ein Ende eines MessageChannel bzw. der Kommunikationskanal eines SharedWorker. Eingehende Nachrichten landen zunächst in einer Port-Nachrichtenwarteschlange, die anfangs deaktiviert ist. Erst mit start() wird die Warteschlange freigegeben und die Nachrichten werden als message-Ereignisse zugestellt.

Wichtig ist der Unterschied zwischen den beiden Wegen, einen Empfänger zu registrieren:

  • Wird die Eigenschaft port.onmessage gesetzt, ruft der Browser start() implizit auf.
  • Wird dagegen port.addEventListener("message", handler) verwendet, muss start() explizit aufgerufen werden – sonst kommen keine Nachrichten an.

Das verzögerte Starten ist bewusst so entworfen: Man kann erst sämtliche Listener registrieren und die Zustellung dann gezielt anstoßen, ohne dass Nachrichten zwischenzeitlich verloren gehen. Bis zum Aufruf werden Nachrichten gepuffert, nicht verworfen.

Beispiele

MessageChannel mit addEventListener – start() ist Pflicht

const { port1, port2 } = new MessageChannel();

port2.addEventListener('message', (event) => {
  console.log('Empfangen:', event.data);
});

// Ohne diesen Aufruf würde der Listener nie ausgelöst
port2.start();

port1.postMessage({ typ: 'gruss', text: 'Hallo Port!' });
Empfangen: { typ: 'gruss', text: 'Hallo Port!' }

onmessage startet den Port implizit

const { port1, port2 } = new MessageChannel();

// Setzen von onmessage ruft start() automatisch auf
port2.onmessage = (event) => console.log('Antwort:', event.data);

port1.postMessage(42);
Antwort: 42

SharedWorker: Port im Worker starten

// shared-worker.js
const verbindungen = new Set();

self.addEventListener('connect', (event) => {
  const port = event.ports[0];
  verbindungen.add(port);

  port.addEventListener('message', (e) => {
    // Nachricht an alle verbundenen Tabs weiterreichen
    for (const p of verbindungen) p.postMessage(e.data);
  });

  port.start(); // nötig wegen addEventListener
});

// main.js
const worker = new SharedWorker('shared-worker.js');
worker.port.addEventListener('message', (e) => console.log('Broadcast:', e.data));
worker.port.start();
worker.port.postMessage('Neuer Tab ist online');
Broadcast: Neuer Tab ist online

Erst Listener sammeln, dann gezielt starten

const { port1, port2 } = new MessageChannel();

// Nachrichten werden gesendet, bevor jemand zuhört – sie werden gepuffert
port1.postMessage('erste');
port1.postMessage('zweite');

const empfangen = [];
port2.addEventListener('message', (e) => empfangen.push(e.data));

setTimeout(() => {
  port2.start(); // jetzt werden beide gepufferten Nachrichten zugestellt
  setTimeout(() => console.log(empfangen), 0);
}, 100);
['erste', 'zweite']

// Wichtig · Fallstricke

  • Häufigster Fehler: addEventListener("message", …) ohne anschließendes start() – es erscheint keine Fehlermeldung, die Nachrichten kommen einfach nicht an.
  • Mehrfaches Aufrufen von start() ist unschädlich; bereits gestartete Ports bleiben unverändert.
  • Der port eines dedizierten Worker bzw. self im Worker benötigt kein start(); das betrifft nur echte MessagePort-Objekte (MessageChannel, SharedWorker, event.ports).
  • Nach close() hat start() keine Wirkung mehr.
  • In Node.js (worker_threads) verhält sich MessagePort ähnlich: port.on('message') startet den Port automatisch, bei addEventListener ist start() nötig.
  • Kompatibilität: in allen modernen Browsern unterstützt; SharedWorker ist jedoch in manchen mobilen Browsern (z. B. älteres Chrome für Android) nicht verfügbar.