Signatur
Beschreibung
Mit cancel() teilt der Verbraucher eines Streams mit, dass er keine weiteren Daten mehr benötigt. Der Aufruf entspricht ReadableStream.prototype.cancel(), wird aber über einen bereits gesperrten Reader ausgelöst. Die zugrunde liegende Quelle erhält den übergebenen Grund (reason) in ihrer cancel(reason)-Callback-Funktion und kann dort Ressourcen freigeben, z. B. eine Netzwerkverbindung schließen oder einen Timer stoppen.
Nach dem Abbruch werden alle noch in der internen Warteschlange liegenden Chunks verworfen. Offene read()-Aufrufe erfüllen sich mit { value: undefined, done: true }, und das closed-Promise des Readers wird erfüllt. Der Stream befindet sich danach im Zustand „geschlossen“.
Typische Einsatzfälle: Sie lesen eine große fetch()-Antwort nur so weit, bis Sie die gesuchte Information gefunden haben, der Nutzer bricht einen Download ab, oder ein Zeitlimit ist überschritten. Wichtig ist der Unterschied zu releaseLock(): releaseLock() gibt nur die Sperre frei, damit ein anderer Reader weiterlesen kann – cancel() beendet den Stream endgültig.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $reason | any | undefined | Frei wählbarer Abbruchgrund (z. B. ein String oder ein Error), der an die cancel()-Callback-Funktion der zugrunde liegenden Quelle weitergereicht wird. |
Rückgabewert
undefined erfüllt, sobald der Stream abgebrochen wurde. Es wird abgelehnt, wenn der Reader nicht mehr an einen Stream gebunden ist (TypeError), der Stream bereits fehlerhaft ist oder die cancel()-Callback-Funktion der Quelle einen Fehler wirft bzw. ein abgelehntes Promise liefert.Beispiele
Download abbrechen, sobald genug Daten gelesen wurden
const readFirstBytes = async (url, limit) => {
const response = await fetch(url);
const reader = response.body.getReader();
let received = 0;
const chunks = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
chunks.push(value);
received += value.byteLength;
if (received >= limit) {
// Restliche Daten werden nicht mehr benötigt
await reader.cancel('Limit erreicht');
break;
}
}
console.log(`Gelesen: ${received} Bytes`);
return chunks;
};
readFirstBytes('https://example.com/', 1024);
Abbruchgrund in der Quelle auswerten und aufräumen
let timer;
const stream = new ReadableStream({
start(controller) {
let i = 0;
timer = setInterval(() => controller.enqueue(`Tick ${i++}`), 100);
},
cancel(reason) {
clearInterval(timer); // Ressourcen freigeben
console.log('Quelle abgebrochen:', reason);
}
});
const reader = stream.getReader();
const { value } = await reader.read();
console.log(value);
await reader.cancel('Nutzer hat abgebrochen');
console.log(await reader.read());
Lesen mit Zeitlimit
const readWithTimeout = async (stream, ms) => {
const reader = stream.getReader();
const timeout = setTimeout(() => {
reader.cancel(new Error('Zeitüberschreitung')).catch(() => {});
}, ms);
try {
let text = '';
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break; // auch nach cancel() erreicht
text += decoder.decode(value, { stream: true });
}
return text;
} finally {
clearTimeout(timeout);
reader.releaseLock();
}
};
const res = await fetch('https://example.com/');
console.log((await readWithTimeout(res.body, 5000)).length);
// Wichtig · Fallstricke
- Daten gehen verloren: Bereits eingereihte, aber noch nicht gelesene Chunks werden verworfen. Brauchen Sie sie noch, verwenden Sie stattdessen
releaseLock(). - Kein Fehlerzustand:
cancel()schließt den Stream regulär – ein laufendesread()liefertdone: true, keinen Fehler. Prüfen Sie ggf. selbst, ob der Abbruch gewollt war. - Nach
releaseLock()wirftcancel()auf demselben Reader ein abgelehntes Promise mitTypeError. - Bei
fetch()-Antworten beendetcancel()in der Regel die Netzwerkübertragung; für einen Abbruch vor dem Lesen ist einAbortControllermeist besser geeignet. - Bei Streams mit
tee()wird die Quelle erst abgebrochen, wenn beide Zweige abgebrochen wurden. - Kompatibilität: In allen aktuellen Browsern verfügbar; in Node.js global ab Version 18 (vorher über
stream/web).