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

ReadableByteStreamController.close()

Methode

Schließt den zugehörigen Byte-Stream. Bereits eingereihte Daten können danach noch gelesen werden, neue Daten nimmt der Stream nicht mehr an.

seit JavaScript Baseline 2023 (Chrome 89, Firefox 102, Safari 16.4 Kategorie: webapi

Signatur

ReadableByteStreamController.prototype.close()

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);
Hallo Welt

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");
Chunk: 8 Bytes Chunk: 8 Bytes Chunk: 7 Bytes 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");
    }
  },
});
TypeError – Stream ist bereits geschlossen