Signatur
Beschreibung
pipeTo() verbindet einen lesbaren Stream mit einem beschreibbaren Ziel. Die Methode liest die Datenstücke (Chunks) nacheinander und schreibt sie ins Ziel. Den Rückstau (Backpressure) berücksichtigt sie dabei automatisch: Ist das Ziel ausgelastet, liest die Methode vorübergehend nicht weiter. Eine eigene Lese- und Schreibschleife mit getReader() und getWriter() brauchen Sie dafür nicht.
Während des Pipings sind beide Streams gesperrt (locked). Sie können also keinen weiteren Reader oder Writer anlegen. Normalerweise gibt das Ende des Quell-Streams das Ende des Ziels vor: Endet die Quelle, wird das Ziel geschlossen. Tritt in der Quelle ein Fehler auf, wird das Ziel abgebrochen. Bricht das Ziel ab, wird die Quelle beendet (cancel). Mit den Optionen preventClose, preventAbort und preventCancel schalten Sie diese Weitergabe einzeln ab.
Typische Einsatzfälle sind das Weiterleiten eines fetch()-Antwortkörpers in eine Datei (File System Access API), in einen eigenen Verarbeitungs-Stream oder in eine Protokollausgabe. Brauchen Sie dagegen eine Kette aus Umwandlungsschritten, ist pipeThrough() mit einem TransformStream meist die bessere Wahl. pipeTo() bildet dann nur das Ende der Kette.
Über die Option signal übergeben Sie ein AbortSignal. Damit lässt sich das Piping jederzeit abbrechen, etwa wenn der Nutzer auf „Abbrechen“ klickt oder eine Zeitüberschreitung eintritt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $destination Pflicht | WritableStream | Das Ziel, in das die Chunks geschrieben werden. Es darf nicht bereits gesperrt sein. | |
| $options | Object | {} | Optionales Objekt, das das Verhalten beim Piping steuert (siehe folgende Einträge). |
| $options.preventClose | boolean | false | Bei true wird das Ziel nicht geschlossen, wenn die Quelle endet. So können Sie später weitere Daten hineinschreiben. |
| $options.preventAbort | boolean | false | Bei true führt ein Fehler in der Quelle nicht zum Abbruch des Ziels. |
| $options.preventCancel | boolean | false | Bei true führt ein Fehler im Ziel nicht zum Beenden (cancel) der Quelle. |
| $options.signal | AbortSignal | Signal zum Abbrechen des Pipings. Beim Abbruch werden Quelle und Ziel entsprechend den prevent*-Optionen beendet bzw. abgebrochen, und das Promise wird mit dem Abbruchgrund abgelehnt. |
Rückgabewert
undefined erfüllt wird, sobald das Piping vollständig abgeschlossen ist. Bei einem Fehler in Quelle oder Ziel oder bei einem Abbruch über signal wird es mit dem jeweiligen Grund abgelehnt.Beispiele
Einfaches Piping in einen protokollierenden WritableStream
const quelle = new ReadableStream({
start(controller) {
['Hallo', 'Stream', 'Welt'].forEach((teil) => controller.enqueue(teil));
controller.close();
}
});
const ziel = new WritableStream({
write(chunk) {
console.log('Empfangen:', chunk);
},
close() {
console.log('Ziel geschlossen');
}
});
await quelle.pipeTo(ziel);
console.log('Piping fertig');
Fetch-Antwort über TransformStream dekodieren und weiterleiten
const response = await fetch('https://example.com/daten.txt');
let zeichen = 0;
await response.body
.pipeThrough(new TextDecoderStream())
.pipeTo(new WritableStream({
write(text) {
zeichen += text.length;
},
close() {
console.log(`Insgesamt ${zeichen} Zeichen gelesen`);
}
}));
Piping mit AbortController und Zeitlimit abbrechen
const controller = new AbortController();
setTimeout(() => controller.abort(new Error('Zeitlimit überschritten')), 2000);
const response = await fetch('https://example.com/grosse-datei.bin');
try {
await response.body.pipeTo(
new WritableStream({ write(chunk) { /* verarbeiten */ } }),
{ signal: controller.signal }
);
console.log('Download komplett');
} catch (err) {
console.error('Abgebrochen:', err.message);
}
Mehrere Quellen nacheinander in ein Ziel schreiben (preventClose)
const erzeuge = (text) => new ReadableStream({
start(c) { c.enqueue(text); c.close(); }
});
const teile = [];
const ziel = new WritableStream({
write(chunk) { teile.push(chunk); },
close() { console.log(teile.join(' ')); }
});
await erzeuge('Teil 1').pipeTo(ziel, { preventClose: true });
await erzeuge('Teil 2').pipeTo(ziel, { preventClose: true });
await ziel.close();
// Wichtig · Fallstricke
- Gesperrte Streams: Ist die Quelle oder das Ziel bereits gesperrt (
locked === true), wird das Promise sofort mit einemTypeErrorabgelehnt. Das passiert zum Beispiel, wenn schon ein Reader existiert oder ein anderes Piping läuft. - Fehler immer behandeln: Ein abgelehntes Promise ohne
catchodertry/awaiterzeugt einen „unhandled rejection“-Fehler. Das gilt auch für einen gewollten Abbruch übersignal. - Abbruchgrund: Rufen Sie
abort()ohne Argument auf, lautet der Grund eineDOMExceptionmit dem NamenAbortError. - Ein Stream wird nur einmal gelesen: Nach dem Piping ist die Quelle aufgebraucht. Brauchen Sie die Daten für zwei Ziele, teilen Sie den Stream vorher mit
tee(). - preventClose hält nur das Ziel offen. Sie müssen es danach selbst schließen, sonst wird z. B. eine Datei nie fertig geschrieben.
- Kompatibilität: Chrome/Edge unterstützen die Methode seit Langem. Firefox unterstützt sie erst seit Version 100, Safari seit 14.1. In Node.js ist sie ab Version 18 global verfügbar (vorher über
stream/web).