Signatur
Beschreibung
throwIfAborted() ist eine Hilfsmethode für abbrechbare, meist asynchrone Abläufe. Ist das AbortSignal bereits abgebrochen (signal.aborted === true), wirft sie synchron den gespeicherten Abbruch-Grund signal.reason. Das ist standardmäßig eine DOMException mit dem Namen "AbortError", bei AbortSignal.timeout() eine mit dem Namen "TimeoutError" oder der Wert, den man an controller.abort(reason) übergeben hat.
Man braucht die Methode vor allem in eigenen Funktionen, die ein signal als Option annehmen. Statt an mehreren Stellen if (signal.aborted) throw signal.reason; zu schreiben, ruft man an passenden Prüfpunkten einfach signal.throwIfAborted() auf. Das sind zum Beispiel der Anfang einer Funktion, die Stelle nach jedem await oder jeder Durchlauf einer langen Schleife. So bricht die Funktion möglichst schnell ab und reicht den Fehler wie fetch() an den Aufrufer weiter.
Wichtig: Die Methode prüft nur den aktuellen Zustand. Einen laufenden Vorgang unterbricht sie nicht von selbst. Wenn eine Operation schon während des Wartens abbrechen soll, braucht man zusätzlich einen Listener für das Ereignis abort.
Rückgabewert
undefined zurück, wenn das Signal nicht abgebrochen ist. Andernfalls wirft die Methode signal.reason.Beispiele
Grundverhalten: vor und nach abort()
const controller = new AbortController();
const { signal } = controller;
signal.throwIfAborted(); // nichts passiert
console.log('noch aktiv');
controller.abort();
try {
signal.throwIfAborted();
} catch (err) {
console.log(err.name, err instanceof DOMException);
}
Abbrechbare Verarbeitung in einer Schleife
const processItems = async (items, { signal } = {}) => {
signal?.throwIfAborted(); // sofort abbrechen, falls schon abgebrochen
const results = [];
for (const item of items) {
// Prüfpunkt nach jedem asynchronen Schritt
await new Promise((r) => setTimeout(r, 100));
signal?.throwIfAborted();
results.push(item * 2);
}
return results;
};
const controller = new AbortController();
setTimeout(() => controller.abort(new Error('Vom Nutzer abgebrochen')), 250);
try {
const res = await processItems([1, 2, 3, 4, 5], { signal: controller.signal });
console.log(res);
} catch (err) {
console.log('Fehler:', err.message);
}
Polling mit Zeitlimit über AbortSignal.timeout()
const waitForReady = async (url, signal) => {
while (true) {
signal.throwIfAborted();
const res = await fetch(url, { signal });
const { ready } = await res.json();
if (ready) return true;
await new Promise((r) => setTimeout(r, 1000));
}
};
try {
await waitForReady('/api/status', AbortSignal.timeout(5000));
console.log('Bereit!');
} catch (err) {
if (err.name === 'TimeoutError') console.log('Zeitlimit überschritten');
else throw err;
}
// Wichtig · Fallstricke
- Kein automatischer Abbruch:
throwIfAborted()prüft nur zum Zeitpunkt des Aufrufs. Soll auch ein laufender Wartevorgang (z. B. einsetTimeout-Promise) sofort abbrechen, braucht man zusätzlichsignal.addEventListener('abort', …, { once: true }). - Der geworfene Wert ist beliebig: Mit
controller.abort('Text')wird ein String geworfen, keinError. Prüft manerr.name === 'AbortError', schlägt das dann fehl. Deshalb am besten immerError-Objekte als Grund übergeben. - Fehler unterscheiden: Bei
AbortSignal.timeout()heißt der Fehler"TimeoutError", nicht"AbortError". Imcatch-Block sollten beide Fälle berücksichtigt werden. - Kompatibilität: Die Methode ist seit 2022 in allen modernen Browsern verfügbar (Chrome/Edge 100, Firefox 97, Safari 15.4) und in Node.js ab 17.3. Für ältere Umgebungen gibt es einen Ersatz:
if (signal.aborted) throw signal.reason ?? new DOMException('Aborted', 'AbortError');. Denn auchsignal.reasongibt es erst seit etwa derselben Zeit. - Bei optionalen Signalen den Aufruf mit
signal?.throwIfAborted()absichern.