Signatur
Beschreibung
Die Methode close() signalisiert dem zugrunde liegenden Ziel (der Underlying Sink), dass keine weiteren Daten mehr kommen. Chunks, die vorher mit write() geschrieben wurden, werden trotzdem noch vollständig abgearbeitet. Erst danach ruft der Stream die Methode close() der Sink auf, etwa um eine Datei zu speichern oder eine Verbindung zu beenden.
Der Rückgabewert ist ein Promise. Es wird erfüllt, wenn alle Chunks geschrieben sind und die Sink ihr close() erfolgreich beendet hat. Es wird abgelehnt, wenn der Stream fehlerhaft ist oder beim Schließen ein Fehler auftritt. Wer await writer.close() schreibt, weiß danach sicher, dass alle Daten angekommen sind.
Nach dem Aufruf wechselt der Stream in den Zustand „closing“. Weitere write()-Aufrufe werden abgelehnt. Das Promise writer.closed erfüllt sich gleichzeitig mit dem Rückgabewert von close(). Die Sperre (Lock) bleibt dabei bestehen, bis man sie mit releaseLock() freigibt.
Typische Einsatzfälle: Dateien über die File System Access API abschließen (FileSystemWritableFileStream), Kompressions- oder Textkodierungs-Pipelines beenden (CompressionStream, TextEncoderStream) oder die Sendeseite einer WebTransport- bzw. WebSocketStream-Verbindung sauber schließen.
Rückgabewert
undefined erfüllt wird, sobald alle Chunks geschrieben sind und der Stream geschlossen ist. Es wird mit einem TypeError abgelehnt, wenn der Stream schon geschlossen wird oder geschlossen ist. Befindet sich der Stream im Fehlerzustand, wird es mit dem gespeicherten Fehler abgelehnt.Beispiele
Einfacher Stream: schreiben und schließen
const chunks = [];
const stream = new WritableStream({
write(chunk) {
chunks.push(chunk);
},
close() {
console.log('Sink geschlossen:', chunks.join(' '));
}
});
const writer = stream.getWriter();
await writer.write('Hallo');
await writer.write('Welt');
await writer.close();
console.log('Alle Daten verarbeitet');
Text komprimieren mit CompressionStream
const komprimieren = async (text) => {
const cs = new CompressionStream('gzip');
const writer = cs.writable.getWriter();
// Lesen parallel starten, damit Backpressure nicht blockiert
const ergebnis = new Response(cs.readable).arrayBuffer();
await writer.write(new TextEncoder().encode(text));
await writer.close(); // signalisiert Ende -> gzip-Footer wird geschrieben
return new Uint8Array(await ergebnis);
};
const bytes = await komprimieren('Lorem ipsum '.repeat(100));
console.log('Komprimiert:', bytes.length, 'Bytes');
Datei per File System Access API speichern
const speichern = async (inhalt) => {
const handle = await window.showSaveFilePicker({ suggestedName: 'notiz.txt' });
const writable = await handle.createWritable();
const writer = writable.getWriter();
try {
await writer.write(inhalt);
await writer.close(); // erst jetzt wird die Datei tatsächlich geschrieben
console.log('Gespeichert');
} catch (err) {
await writer.abort(err).catch(() => {});
console.error('Fehler beim Speichern:', err);
}
};
document.querySelector('#save').addEventListener('click', () => speichern('Hallo Datei'));
Fehler beim doppelten Schließen abfangen
const writer = new WritableStream().getWriter();
await writer.close();
try {
await writer.close();
} catch (err) {
console.log(err.name);
}
try {
await writer.write('zu spät');
} catch (err) {
console.log('write nach close:', err.name);
}
// Wichtig · Fallstricke
- Auf das Promise warten: Ohne
await writer.close()weiß man nicht, ob die Daten wirklich gespeichert wurden. Das gilt besonders fürFileSystemWritableFileStream: Dort wird die Datei erst beim Schließen geschrieben. Wird der Aufruf vergessen, gehen die Daten verloren. - Deadlock durch Backpressure: Bei Transform-Streams wie
CompressionStreamkann das Promise vonclose()hängen bleiben, solange niemand die lesbare Seite liest. Deshalb das Lesen vor demawaitstarten. - close() und abort():
close()beendet den Stream geordnet, wartende Chunks werden noch verarbeitet.abort()bricht dagegen sofort ab und verwirft sie. - Ein zweiter
close()-Aufruf oderwrite()nach dem Schließen führt zu einem abgelehnten Promise mitTypeError. Ist der Writer bereits freigegeben (releaseLock()), wird ebenfalls mitTypeErrorabgelehnt. - Alternativ lässt sich
WritableStream.prototype.close()direkt aufrufen, allerdings nur, wenn der Stream nicht gesperrt ist. - Kompatibilität: In Chrome, Edge und Safari schon lange verfügbar. Firefox unterstützt
WritableStreamvollständig erst seit Version 100. In Node.js ist die API ab Version 18 global verfügbar, davor überstream/web.