Start · Sprachen · JavaScript · Referenz · new ByteLengthQueuingStrategy()

new ByteLengthQueuingStrategy()

Methode

Erstellt eine Warteschlangen-Strategie für Streams, die die Größe jedes Chunks anhand seiner <code>byteLength</code> misst und so Gegendruck (Backpressure) in Bytes steuert.

seit JavaScript Baseline: alle modernen Browser (seit 2022), Node. Kategorie: webapi

Signatur

new ByteLengthQueuingStrategy({ highWaterMark })

Beschreibung

Der Konstruktor ByteLengthQueuingStrategy() erzeugt eine Queuing-Strategie für die Streams API. Sie wird als zweites Argument an new ReadableStream() bzw. new WritableStream() übergeben (bei TransformStream als zweites oder drittes Argument) und legt fest, wie die interne Warteschlange eines Streams gefüllt wird.

Anders als bei der CountQueuingStrategy, die jeden Chunk als Größe 1 zählt, misst diese Strategie jeden Chunk über seine Eigenschaft byteLength. Das ist sinnvoll, wenn Chunks binäre Daten sind, also ArrayBuffer, Uint8Array oder andere TypedArrays bzw. DataView, und der Speicherverbrauch in Bytes begrenzt werden soll.

Der Wert highWaterMark gibt an, wie viele Bytes in der Warteschlange liegen dürfen, bevor Gegendruck entsteht. Überschreitet die Summe der Chunk-Größen diesen Wert, wird controller.desiredSize null oder negativ, pull() wird nicht mehr aufgerufen und writer.ready bleibt unerfüllt, bis wieder Platz frei ist. Es handelt sich um einen Schwellwert, keine harte Grenze: Chunks werden trotzdem angenommen.

Parameter

Name Typ Default Beschreibung
$options Pflicht Object Konfigurationsobjekt mit der Eigenschaft highWaterMark.
$options.highWaterMark Pflicht number Maximale Gesamtgröße in Bytes, die in der internen Warteschlange liegen darf, bevor Gegendruck ausgelöst wird. Nicht-negative Zahl, Infinity ist erlaubt.

Beispiele

Instanz erzeugen und Eigenschaften prüfen

const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 1024 });

console.log(strategy.highWaterMark);
console.log(strategy.size(new Uint8Array(256)));
console.log(strategy.size(new ArrayBuffer(4096)));
1024 256 4096

ReadableStream mit Byte-basiertem Puffer

const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 16 * 1024 });

let sent = 0;
const stream = new ReadableStream({
  pull(controller) {
    // Wird nur aufgerufen, solange weniger als 16 KiB gepuffert sind
    const chunk = new Uint8Array(4096).fill(sent % 256);
    controller.enqueue(chunk);
    sent++;
    console.log(`Chunk ${sent}, desiredSize: ${controller.desiredSize}`);
    if (sent === 4) controller.close();
  }
}, strategy);

const reader = stream.getReader();
let total = 0;
for (;;) {
  const { done, value } = await reader.read();
  if (done) break;
  total += value.byteLength;
}
console.log(`Gelesen: ${total} Bytes`);
Chunk 1, desiredSize: 12288 ... Gelesen: 16384 Bytes

WritableStream mit Gegendruck über writer.ready

const sink = new WritableStream({
  async write(chunk) {
    // Langsames Ziel simulieren, z. B. Upload oder Festplatte
    await new Promise((r) => setTimeout(r, 50));
    console.log(`Geschrieben: ${chunk.byteLength} Bytes`);
  }
}, new ByteLengthQueuingStrategy({ highWaterMark: 8192 }));

const writer = sink.getWriter();
for (let i = 0; i < 4; i++) {
  await writer.ready; // wartet, sobald mehr als 8 KiB in der Warteschlange liegen
  writer.write(new Uint8Array(4096));
}
await writer.close();
Geschrieben: 4096 Bytes Geschrieben: 4096 Bytes Geschrieben: 4096 Bytes Geschrieben: 4096 Bytes

// Wichtig · Fallstricke

  • Nur für binäre Chunks: Strings haben keine Eigenschaft byteLength. size() liefert dann undefined, und der Stream bricht beim Einreihen mit einem RangeError ab. Text vorher mit TextEncoder umwandeln oder CountQueuingStrategy verwenden.
  • highWaterMark muss angegeben werden. Fehlt es, wirft der Konstruktor einen TypeError. Negative Werte oder NaN führen erst beim Erzeugen des Streams zu einem RangeError.
  • Für Byte-Streams (new ReadableStream({ type: \"bytes\" })) darf keine Strategie mit size() übergeben werden. Dort nur { highWaterMark } angeben, sonst gibt es einen RangeError.
  • highWaterMark ist ein weicher Schwellwert. Ein einzelner sehr großer Chunk wird trotzdem vollständig angenommen.
  • Kompatibilität: in Chrome, Edge, Firefox und Safari verfügbar, in Node.js ab Version 18 global (vorher über stream/web). Auch in Web Workern nutzbar.