Start · Sprachen · JavaScript · Referenz · WritableStream.getWriter()

WritableStream.getWriter()

Methode

Gibt einen neuen <code>WritableStreamDefaultWriter</code> zurück und sperrt den <code>WritableStream</code> exklusiv für diesen Writer.

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

Signatur

WritableStream.prototype.getWriter()

Beschreibung

Mit getWriter() holst du dir einen WritableStreamDefaultWriter, über den du Daten mit write() in einen WritableStream schreibst, den Stream mit close() schließt oder mit abort() abbrichst. Solange der Writer aktiv ist, ist der Stream gesperrt (stream.locked === true). Andere Writer oder pipeTo()-Aufrufe können dann nicht darauf zugreifen.

Die Sperre sorgt dafür, dass immer nur ein Produzent gleichzeitig in den Stream schreibt und die Reihenfolge der Chunks erhalten bleibt. Brauchst du den Stream später für einen anderen Writer oder eine Pipe, gibst du die Sperre mit writer.releaseLock() wieder frei.

Der Writer bringt zusätzlich Hilfsmittel für den Rückstau (Backpressure) mit: writer.ready ist ein Promise, das sich erfüllt, sobald die interne Warteschlange wieder Platz hat, und writer.desiredSize gibt an, wie viel Platz aktuell frei ist. Wenn du auf ready wartest, bevor du schreibst, läuft der Speicher bei großen Datenmengen nicht voll.

Rückgabewert

Typ
WritableStreamDefaultWriter
Beschreibung
Ein neuer WritableStreamDefaultWriter, der an den Stream gebunden ist. Ab diesem Zeitpunkt ist der Stream gesperrt.

Beispiele

Writer holen und Daten schreiben

const chunks = [];
const stream = new WritableStream({
  write(chunk) {
    chunks.push(chunk);
  },
  close() {
    console.log('Fertig:', chunks.join(' '));
  }
});

const writer = stream.getWriter();
console.log('gesperrt:', stream.locked);

await writer.write('Hallo');
await writer.write('Welt');
await writer.close();
gesperrt: true Fertig: Hallo Welt

Rückstau beachten mit writer.ready

const stream = new WritableStream(
  {
    async write(chunk) {
      // langsamen Empfänger simulieren
      await new Promise((r) => setTimeout(r, 50));
      console.log('verarbeitet:', chunk);
    }
  },
  new CountQueuingStrategy({ highWaterMark: 2 })
);

const writer = stream.getWriter();

for (let i = 1; i <= 5; i++) {
  await writer.ready; // warten, bis die Warteschlange wieder Platz hat
  writer.write(`Paket ${i}`);
}
await writer.close();
verarbeitet: Paket 1 verarbeitet: Paket 2 verarbeitet: Paket 3 verarbeitet: Paket 4 verarbeitet: Paket 5

Sperre freigeben und zweiten Writer nutzen

const stream = new WritableStream({
  write(chunk) { console.log('empfangen:', chunk); }
});

const first = stream.getWriter();
await first.write('A');

try {
  stream.getWriter(); // Stream ist noch gesperrt
} catch (err) {
  console.log(err.name);
}

first.releaseLock();
const second = stream.getWriter();
await second.write('B');
await second.close();
empfangen: A TypeError empfangen: B

Text in einen komprimierenden Stream schreiben

const { readable, writable } = new CompressionStream('gzip');
const writer = writable.getWriter();
const encoder = new TextEncoder();

writer.write(encoder.encode('Viel Text '.repeat(100)));
writer.close();

const blob = await new Response(readable).blob();
console.log('komprimierte Größe:', blob.size, 'Bytes');
komprimierte Größe: ca. 40 Bytes

// Wichtig · Fallstricke

  • TypeError bei gesperrtem Stream: Ist der Stream schon gesperrt (durch einen anderen Writer oder durch readable.pipeTo(stream)), wirft getWriter() einen TypeError. Mit stream.locked kannst du das vorher prüfen.
  • releaseLock() schließt nicht: writer.releaseLock() hebt nur die Sperre auf, der Stream bleibt offen. Zum Beenden rufst du writer.close() auf. Wurde die Sperre freigegeben, während noch Schreibvorgänge ausstehen, werden deren Promises abgelehnt.
  • Fehler nicht übersehen: Gibst du den Promise von write() nicht mit await zurück, landen Fehler als unbehandelte Promise-Ablehnung. Fehler solltest du spätestens über await writer.close() oder writer.closed abfangen.
  • Kompatibilität: Wird in allen modernen Browsern unterstützt (Firefox erst ab Version 100). In Node.js gibt es die Methode als stream/web ab Version 16.5, global verfügbar ab Version 18.