Start · Sprachen · JavaScript · Referenz · ReadableStreamBYOBRequest.view

ReadableStreamBYOBRequest.view

Eigenschaft

Gibt die <code>ArrayBufferView</code> zurück, in die eine zugrunde liegende Byte-Quelle Daten für die aktuelle BYOB-Leseanforderung schreiben soll, oder <code>null</code>.

seit JavaScript Baseline 2024: Chrome 89, Firefox 102, Safari 18.2 Kategorie: webapi

Signatur

get ReadableStreamBYOBRequest.prototype.view

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

Typ
Uint8Array | null
Beschreibung
Eine Ansicht auf den bereitgestellten Zielpuffer, bei der 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
}
[0, 1, 2, 3] [4, 5, 6, 7]

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));
vorher: 10 nachher: null Hi

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');
gelesen: 1024 Bytes

// Wichtig · Fallstricke

  • Nur bei Byte-Streams: controller.byobRequest gibt es nur, wenn die Quelle mit type: "bytes" erstellt wurde. Bei Standard-Streams existiert kein BYOB-Request.
  • Auf null prüfen: Liest der Konsument mit einem Standard-Leser ohne autoAllocateChunkSize, ist controller.byobRequest null. Liefere die Daten dann mit controller.enqueue().
  • Offsets beachten: view.byteOffset ist nicht zwingend 0. Schreibe über die View selbst, etwa mit view[i] oder view.set(), und nicht direkt in view.buffer ab Index 0.
  • Gültige Antwortwerte: respond(n) muss mit 0 < n ≤ view.byteLength aufgerufen werden. Nur ein geschlossener Stream erlaubt respond(0), sonst wird ein RangeError bzw. TypeError geworfen.
  • Übertragene Puffer: Der vom Leser übergebene ArrayBuffer wird übertragen (detached). Nach read() musst du value.buffer weiterverwenden, 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".