Signatur
Beschreibung
Die schreibgeschützte Eigenschaft view eines ReadableStreamBYOBRequest liefert den Zielpuffer einer laufenden Leseanforderung als Uint8Array. BYOB steht für „Bring Your Own Buffer“: Der Leser (ReadableStreamBYOBReader) stellt einen eigenen Puffer bereit. Die zugrunde liegende Byte-Quelle schreibt dann direkt in diesen Speicher, ohne dass Daten zusätzlich kopiert werden müssen.
Auf das Objekt greifst du in den Callbacks pull() oder start() einer Byte-Quelle (type: "bytes") über controller.byobRequest zu. Du schreibst Bytes ab Index 0 in view und meldest danach mit byobRequest.respond(bytesWritten), wie viele Bytes tatsächlich geschrieben wurden. Alternativ übergibst du mit respondWithNewView(view) eine neue Ansicht auf denselben Puffer.
Hat der Leser gerade keine Anforderung offen oder ist die Anforderung schon beantwortet, gibt controller.byobRequest null zurück. Nach respond() liefert view selbst ebenfalls null. Die Länge von view kann kleiner sein als der Puffer, den der Leser übergeben hat, wenn in einer früheren Antwort nur ein Teil gefüllt wurde. Richte dich daher immer nach view.byteLength.
Rückgabewert
byteOffset und byteLength den noch zu füllenden Bereich angeben. null, wenn die Anforderung bereits beantwortet wurde.Beispiele
Byte-Quelle, die direkt in den Puffer des Lesers schreibt
let counter = 0;
const stream = new ReadableStream({
type: 'bytes',
pull(controller) {
const request = controller.byobRequest;
if (!request) return; // keine BYOB-Anforderung offen
const view = request.view; // Uint8Array
// Bis zu 4 Bytes mit fortlaufenden Werten füllen
const n = Math.min(4, view.byteLength);
for (let i = 0; i < n; i++) view[i] = counter++;
request.respond(n);
if (counter >= 8) controller.close();
}
});
const reader = stream.getReader({ mode: 'byob' });
let buffer = new ArrayBuffer(16);
while (true) {
const { value, done } = await reader.read(new Uint8Array(buffer));
if (done) break;
console.log(Array.from(value));
buffer = value.buffer; // Puffer wurde übertragen – wiederverwenden
}
view nach respond() prüfen
const stream = new ReadableStream({
type: 'bytes',
pull(controller) {
const req = controller.byobRequest;
console.log('vorher:', req.view.byteLength);
req.view.set([72, 105]); // "Hi"
req.respond(2);
console.log('nachher:', req.view);
controller.close();
}
});
const reader = stream.getReader({ mode: 'byob' });
const { value } = await reader.read(new Uint8Array(10));
console.log(new TextDecoder().decode(value));
Datei-Chunks mit Node.js in die view lesen
import { open } from 'node:fs/promises';
const file = await open('./daten.bin');
const stream = new ReadableStream({
type: 'bytes',
async pull(controller) {
const view = controller.byobRequest.view;
const { bytesRead } = await file.read(view, 0, view.byteLength, null);
if (bytesRead === 0) {
await file.close();
controller.close();
controller.byobRequest.respond(0); // offene Anforderung auflösen
} else {
controller.byobRequest.respond(bytesRead);
}
}
});
const reader = stream.getReader({ mode: 'byob' });
const { value } = await reader.read(new Uint8Array(1024));
console.log('gelesen:', value.byteLength, 'Bytes');
// Wichtig · Fallstricke
- Nur bei Byte-Streams:
controller.byobRequestgibt es nur, wenn die Quelle mittype: "bytes"erstellt wurde. Bei Standard-Streams existiert kein BYOB-Request. - Auf
nullprüfen: Liest der Konsument mit einem Standard-Leser ohneautoAllocateChunkSize, istcontroller.byobRequestnull. Liefere die Daten dann mitcontroller.enqueue(). - Offsets beachten:
view.byteOffsetist nicht zwingend 0. Schreibe über die View selbst, etwa mitview[i]oderview.set(), und nicht direkt inview.bufferab Index 0. - Gültige Antwortwerte:
respond(n)muss mit0 < n ≤ view.byteLengthaufgerufen werden. Nur ein geschlossener Stream erlaubtrespond(0), sonst wird einRangeErrorbzw.TypeErrorgeworfen. - Übertragene Puffer: Der vom Leser übergebene
ArrayBufferwird übertragen (detached). Nachread()musst duvalue.bufferweiterverwenden, nicht den ursprünglichen Puffer. - Kompatibilität: Safari unterstützt BYOB-Streams erst seit Version 18.2. Bei älteren Browsern vorher prüfen, z. B. mit
typeof ReadableStreamBYOBReader !== "undefined".