Signatur
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);
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();
// };
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 neuenMessageChannelerstellen. - Speicherlecks: Ports mit gesetztem
onmessageoder 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_threadslöstport.close()auf beiden Seiten das Ereignis'close'aus. Außerdem hält ein offener Port den Prozess am Leben, bis er geschlossen oder mitunref()freigegeben wird.