Signatur
Beschreibung
AbortSignal.reason enthält den Wert, mit dem ein Signal abgebrochen wurde. Das ist entweder der Wert, den man an AbortController.prototype.abort(reason) oder AbortSignal.abort(reason) übergibt, oder – wenn kein Grund angegeben wurde – eine DOMException mit dem Namen "AbortError". Bei AbortSignal.timeout() ist der Grund eine DOMException mit dem Namen "TimeoutError".
Solange das Signal nicht abgebrochen ist (signal.aborted === false), ist reason undefined. Nach dem Abbruch ändert sich der Wert nicht mehr – ein Signal kann nur einmal abgebrochen werden.
Die Eigenschaft ist nützlich, um in eigenen abbrechbaren Funktionen den richtigen Fehler weiterzugeben, um zwischen einem Abbruch durch den Nutzer und einem Timeout zu unterscheiden oder um in einem abort-Event-Handler auszuwerten, warum abgebrochen wurde. Web-APIs wie fetch() lehnen ihr Promise bei einem Abbruch direkt mit signal.reason ab.
Rückgabewert
DOMException ("AbortError" bzw. "TimeoutError") als Standardwert oder undefined, wenn das Signal noch nicht abgebrochen wurde.Beispiele
Standardgrund und eigener Grund
const c1 = new AbortController();
console.log(c1.signal.reason); // noch nicht abgebrochen
c1.abort();
console.log(c1.signal.reason.name);
const c2 = new AbortController();
c2.abort(new Error('Nutzer hat abgebrochen'));
console.log(c2.signal.reason.message);
Timeout von Nutzerabbruch unterscheiden
const controller = new AbortController();
const signal = AbortSignal.any([
controller.signal,
AbortSignal.timeout(3000)
]);
try {
const res = await fetch('https://example.com/api/daten', { signal });
console.log(await res.json());
} catch (err) {
if (signal.aborted && signal.reason?.name === 'TimeoutError') {
console.warn('Server antwortet zu langsam');
} else if (signal.aborted) {
console.info('Abgebrochen:', signal.reason);
} else {
throw err; // echter Netzwerkfehler
}
}
Eigene abbrechbare Funktion mit reason
const warte = (ms, { signal } = {}) => new Promise((resolve, reject) => {
if (signal?.aborted) return reject(signal.reason);
const id = setTimeout(resolve, ms);
signal?.addEventListener('abort', () => {
clearTimeout(id);
reject(signal.reason);
}, { once: true });
});
const controller = new AbortController();
setTimeout(() => controller.abort('Seite verlassen'), 500);
try {
await warte(2000, { signal: controller.signal });
} catch (grund) {
console.log('Abbruchgrund:', grund);
}
throwIfAborted() nutzt reason
const controller = new AbortController();
controller.abort(new RangeError('Limit erreicht'));
try {
controller.signal.throwIfAborted();
} catch (e) {
console.log(e === controller.signal.reason, e.name);
}
// Wichtig · Fallstricke
- Beliebiger Typ:
reasonkann jeder Wert sein – auch ein String, eine Zahl odernull. Nicht blind aufreason.namezugreifen; optionales Verketten (reason?.name) verwenden oder mitinstanceofprüfen. Am besten übergibt man stets einError-Objekt, damit ein Stacktrace entsteht. abort(undefined): Wird explizitundefinedübergeben, setzt der Browser trotzdem die Standard-DOMException"AbortError".- Abbruch zuverlässig prüfen: Mit
signal.abortedprüfen, nicht überreason !== undefined. - Ältere Umgebungen: Vor Chrome 98, Firefox 97, Safari 15.4 bzw. Node.js 17.2 gibt es
reasonnicht;fetch()lehnt dort immer mit einem allgemeinenAbortErrorab, und ein eigener Grund geht verloren. Einige Bibliotheken und ältere Polyfills reichenreasonebenfalls nicht weiter. - Die Eigenschaft ist nur lesbar; eine Zuweisung wird ignoriert (im Strict Mode gibt es einen
TypeError).