Signatur
Beschreibung
respond() ist das Gegenstück zum BYOB-Lesen (Bring Your Own Buffer): Ruft ein Konsument ReadableStreamBYOBReader.read(view) auf, stellt der Strom der Quelle über controller.byobRequest einen Ausschnitt dieses Puffers bereit. Die zugrunde liegende Quelle schreibt die Daten direkt in byobRequest.view und meldet mit respond(bytesWritten), wie viele Bytes gültig sind. So werden Kopien vermieden, was bei großen Binärdaten (Dateien, Netzwerk-Sockets, Dekompression) Speicher und Rechenzeit spart.
Nach dem Aufruf wird der zugrunde liegende ArrayBuffer übertragen (transferiert): Die bisherige view ist danach abgekoppelt (byteLength 0), und die Anforderung ist erledigt. Der Konsument erhält die Daten als neue View über denselben Speicher im Ergebnis von read(). Es dürfen weniger Bytes gemeldet werden, als die View fasst. Der Rest bleibt dann für eine spätere Antwort offen, sofern der Reader eine Mindestmenge verlangt hat.
Verwende respond(), wenn du in die bereitgestellte View geschrieben hast. Hast du die Daten dagegen in einem eigenen Puffer, nimm respondWithNewView() oder controller.enqueue(). Ist der Strom mit controller.close() geschlossen worden, während noch eine BYOB-Anforderung offen ist, muss sie mit respond(0) abgeschlossen werden. Nur so wird der wartende read()-Aufruf mit done: true aufgelöst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $bytesWritten Pflicht | number | Anzahl der Bytes, die ab dem Anfang von byobRequest.view geschrieben wurden. Im Zustand readable muss der Wert größer als 0 sein und darf view.byteLength nicht übersteigen. Nach controller.close() muss er genau 0 sein. |
Rückgabewert
read()-Promise des BYOB-Readers erfüllt, sobald genug Bytes vorliegen.Beispiele
Bytequelle, die direkt in den Puffer des Konsumenten schreibt
const data = new TextEncoder().encode("Hallo BYOB-Welt!");
let offset = 0;
const stream = new ReadableStream({
type: "bytes",
pull(controller) {
const request = controller.byobRequest;
if (offset >= data.length) {
controller.close();
request?.respond(0); // offene Anforderung nach close() abschließen
return;
}
const view = request.view; // Uint8Array über den Puffer des Lesers
const n = Math.min(view.byteLength, data.length - offset);
view.set(data.subarray(offset, offset + n));
offset += n;
request.respond(n); // n Bytes sind gültig
}
});
const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(5);
while (true) {
const { value, done } = await reader.read(new Uint8Array(buffer));
if (done) break;
console.log(new TextDecoder().decode(value));
buffer = value.buffer; // übertragenen Puffer wiederverwenden
}
Zufallsbytes mit autoAllocateChunkSize (auch für Standard-Reader)
const randomStream = new ReadableStream({
type: "bytes",
autoAllocateChunkSize: 16, // byobRequest existiert auch beim Standard-Reader
pull(controller) {
const { view } = controller.byobRequest;
crypto.getRandomValues(view);
controller.byobRequest.respond(view.byteLength);
}
});
const reader = randomStream.getReader();
const { value } = await reader.read();
console.log(value.byteLength);
reader.cancel();
Fehlerfall: mehr Bytes melden als die View fasst
const stream = new ReadableStream({
type: "bytes",
pull(controller) {
const request = controller.byobRequest;
try {
request.respond(request.view.byteLength + 1);
} catch (err) {
console.log(err.name);
controller.error(err);
}
}
});
const reader = stream.getReader({ mode: "byob" });
await reader.read(new Uint8Array(4)).catch((e) => console.log("Lesen fehlgeschlagen:", e.name));
// Wichtig · Fallstricke
- Nur einmal aufrufen: Nach
respond()ist die Anforderung erledigt, undbyobRequest.viewistnull. Ein zweiter Aufruf löst einenTypeErroraus. Hol dir für die nächste Anforderung ein neuescontroller.byobRequest. - Abgekoppelte View: Referenzen auf die alte
viewoder ihrenbuffersind nach dem Aufruf unbrauchbar (byteLength0). Schreib nichts mehr hinein. - Ausnahmen:
TypeError, wenn die Anforderung nicht mehr zum Controller gehört, der Puffer abgekoppelt ist oder im Zustand readable0übergeben wird.RangeError, wennbytesWrittengrößer als die View ist oder nachclose()ungleich0ist. controller.byobRequestistnull, wenn keine BYOB-Leseanforderung ansteht. Das ist z. B. beim Standard-Reader ohneautoAllocateChunkSizeder Fall. Prüfe den Wert daher vor dem Zugriff.- Funktioniert nur bei Strömen mit
type: \"bytes\". Unterstützung gibt es in allen aktuellen Browsern (Safari erst ab 16.4) und in Node.js überstream/webbzw. global ab Version 18.