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

MessagePort.close()

Methode

Trennt einen <code>MessagePort</code> dauerhaft: Er kann danach keine Nachrichten mehr senden oder empfangen, und die Verbindung zum Partner-Port ist aufgehoben.

seit JavaScript Baseline: alle Browser (seit 2015), Node.js 10.5+ Kategorie: webapi

Signatur

MessagePort.prototype.close()

Beschreibung

Die Methode close() beendet die Kommunikation über einen MessagePort. Nach dem Aufruf werden über diesen Port keine Nachrichten mehr zugestellt, und Aufrufe von postMessage() auf ihm werden stillschweigend ignoriert. Auch der Partner-Port des zugehörigen MessageChannel ist danach „verwaist“: Was er sendet, kommt nirgends mehr an.

Man verwendet close(), wenn ein Kommunikationskanal, etwa zwischen Hauptthread und einem Worker, einem iframe oder einem SharedWorker, nicht mehr gebraucht wird. So können Ressourcen freigegeben werden, und es werden keine veralteten Nachrichten mehr verarbeitet. Das ist besonders wichtig bei kurzlebigen Anfrage-Antwort-Kanälen, bei denen für jede Anfrage ein eigener MessageChannel erzeugt wird.

Die Methode ist nicht umkehrbar. Ein geschlossener Port lässt sich weder mit start() wieder öffnen noch sinnvoll an einen anderen Kontext übertragen. Für eine neue Verbindung muss ein neuer MessageChannel angelegt werden. Bereits in der Warteschlange stehende, noch nicht zugestellte Nachrichten können beim Schließen verloren gehen.

Beispiele

Einfaches Schließen eines MessageChannel-Ports

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

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

port1.postMessage('Hallo');

// Nach kurzer Zeit den Kanal schließen
setTimeout(() => {
  port1.close();
  port1.postMessage('Kommt nie an'); // wird ignoriert, kein Fehler
  console.log('port1 geschlossen');
}, 100);
Empfangen: Hallo port1 geschlossen

Anfrage-Antwort-Muster mit Worker: Port nach Antwort schließen

// main.js
const worker = new Worker('worker.js');

const request = (payload) =>
  new Promise((resolve) => {
    const { port1, port2 } = new MessageChannel();
    port1.onmessage = (event) => {
      resolve(event.data);
      port1.close(); // Kanal wird nicht mehr benötigt
    };
    worker.postMessage(payload, [port2]);
  });

const result = await request({ a: 2, b: 3 });
console.log('Summe:', result);

// worker.js
// self.onmessage = (event) => {
//   const [port] = event.ports;
//   const { a, b } = event.data;
//   port.postMessage(a + b);
//   port.close();
// };
Summe: 5

Verbindung zu einem iframe beim Verlassen sauber trennen

const iframe = document.querySelector('iframe');
const channel = new MessageChannel();

channel.port1.onmessage = (event) => {
  console.log('Nachricht vom iframe:', event.data);
};

iframe.addEventListener('load', () => {
  // Hier die tatsächliche Herkunft statt '*' angeben
  iframe.contentWindow.postMessage('init', 'https://example.com', [channel.port2]);
});

window.addEventListener('pagehide', () => {
  channel.port1.close();
});

// Wichtig · Fallstricke

  • Kein close-Ereignis beim Partner (in älteren Browsern): Lange Zeit hat die Gegenseite nicht mitbekommen, dass ein Port geschlossen wurde. Neuere Chromium-Versionen feuern ein close-Ereignis auf dem Partner-Port, aber das wird nicht überall unterstützt. Wer darauf nicht verzichten kann, sollte vor dem Schließen eine eigene „Tschüss“-Nachricht senden.
  • Stille Fehler: postMessage() auf einem geschlossenen Port wirft keine Ausnahme. Nachrichten gehen einfach verloren.
  • Nicht umkehrbar: Nach close() ist der Port dauerhaft unbrauchbar. Für eine neue Verbindung muss man einen neuen MessageChannel erstellen.
  • Speicherlecks: Ports mit gesetztem onmessage oder aktivem Listener werden nicht vom Garbage Collector entfernt, solange sie offen sind. Kurzlebige Kanäle sollte man deshalb immer ausdrücklich schließen.
  • Node.js: In worker_threads löst port.close() auf beiden Seiten das Ereignis 'close' aus. Außerdem hält ein offener Port den Prozess am Leben, bis er geschlossen oder mit unref() freigegeben wird.