Signatur
Beschreibung
Mit close() teilt eine zugrunde liegende Byte-Quelle (underlying byte source) mit, dass keine weiteren Daten mehr kommen. Sie rufen die Methode im start()- oder pull()-Callback eines ReadableStream mit type: "bytes" auf, zum Beispiel wenn eine Datei, ein Socket oder ein Puffer vollständig ausgelesen ist.
Der Stream wird dabei nicht sofort gewaltsam beendet. Liegen noch Bytes in der internen Warteschlange, merkt sich der Controller zunächst nur die Schließanforderung. Leser erhalten die restlichen Daten, und erst danach meldet read() den Wert { done: true }. Ist die Warteschlange leer, wechselt der Stream sofort in den Zustand closed, und das Promise reader.closed wird erfüllt.
Bei BYOB-Lesern (getReader({ mode: "byob" })) gibt es eine Besonderheit: Wartet gerade eine Leseanfrage (controller.byobRequest), müssen Sie diese nach close() mit byobRequest.respond(0) beantworten. Erst dann wird der ausstehende read()-Aufruf mit done: true abgeschlossen und der Puffer an den Leser zurückgegeben.
Wenn Sie den Stream wegen eines Fehlers beenden wollen, nehmen Sie stattdessen controller.error(reason). close() steht immer für ein reguläres Ende.
Beispiele
Byte-Stream mit festen Daten befüllen und schließen
const encoder = new TextEncoder();
const stream = new ReadableStream({
type: "bytes",
start(controller) {
controller.enqueue(encoder.encode("Hallo "));
controller.enqueue(encoder.encode("Welt"));
// Keine weiteren Daten – bereits eingereihte Chunks bleiben lesbar
controller.close();
},
});
const text = await new Response(stream).text();
console.log(text);
Puffer per BYOB-Leser ausgeben und am Ende schließen
const source = new TextEncoder().encode("Streams sind praktisch!"); // 23 Bytes
let offset = 0;
const stream = new ReadableStream({
type: "bytes",
autoAllocateChunkSize: 8,
pull(controller) {
const request = controller.byobRequest;
const view = request.view;
const remaining = source.length - offset;
if (remaining === 0) {
controller.close();
// Ausstehende BYOB-Anfrage mit 0 Bytes abschließen
request.respond(0);
return;
}
const n = Math.min(view.byteLength, remaining);
new Uint8Array(view.buffer, view.byteOffset, n)
.set(source.subarray(offset, offset + n));
offset += n;
request.respond(n);
},
});
const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(8);
while (true) {
const { value, done } = await reader.read(new Uint8Array(buffer));
if (done) break;
console.log(`Chunk: ${value.byteLength} Bytes`);
buffer = value.buffer; // übertragenen Puffer wiederverwenden
}
console.log("Stream geschlossen");
Zweites close() löst einen TypeError aus
new ReadableStream({
type: "bytes",
start(controller) {
controller.close();
try {
controller.close();
} catch (err) {
console.log(err.name, "–", "Stream ist bereits geschlossen");
}
},
});