Signatur
Beschreibung
Das abort-Ereignis tritt genau einmal auf, nämlich wenn ein AbortSignal vom Zustand „nicht abgebrochen“ in „abgebrochen“ wechselt. Dafür gibt es mehrere Wege: Aufruf von AbortController.prototype.abort(), Ablauf eines mit AbortSignal.timeout() erzeugten Signals oder das Abbrechen eines der Quellsignale bei AbortSignal.any(). Wenn das Ereignis ausgelöst wird, sind signal.aborted schon true und signal.reason schon gesetzt.
Man registriert den Handler entweder mit signal.addEventListener("abort", handler) oder über die Eigenschaft signal.onabort = handler. Das Ereignis ist ein einfaches Event ohne Zusatzdaten. Es steigt nicht auf (bubbles), und man kann es nicht abbrechen (nicht cancelable). Den Abbruchgrund liest du über event.target.reason bzw. signal.reason.
Wichtig ist das Ereignis vor allem dann, wenn du eigene abbrechbare APIs baust: Timer, WebSocket-Verbindungen, Worker-Aufgaben oder langlaufende Promises lassen sich so an dasselbe Signal hängen, das auch fetch() steuert. Browser-APIs wie fetch oder addEventListener (Option signal) reagieren intern von selbst auf das Signal, dort brauchst du also keinen eigenen Handler.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "abort". |
|
| $handler Pflicht | (event: Event) => void | EventListenerObject | Callback, der beim Abbruch aufgerufen wird. event.target ist das betroffene AbortSignal. |
|
| $options | boolean | AddEventListenerOptions | false | Übliche Optionen von addEventListener. { once: true } ist sinnvoll, damit der Listener nach dem einmaligen Auslösen sicher entfernt wird. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein Event-Objekt mit type === "abort".Beispiele
Abbruch mit addEventListener beobachten
const controller = new AbortController();
const { signal } = controller;
signal.addEventListener('abort', (event) => {
console.log('Abgebrochen:', event.target.reason.name);
}, { once: true });
controller.abort();
console.log('aborted?', signal.aborted);
onabort-Eigenschaft mit eigenem Grund
const controller = new AbortController();
controller.signal.onabort = () => {
console.log('Grund:', controller.signal.reason);
};
controller.abort('Benutzer hat abgebrochen');
// Ein zweiter Aufruf löst kein weiteres Ereignis aus
controller.abort('noch einmal');
Eigene abbrechbare Promise (sleep)
const sleep = (ms, { signal } = {}) => new Promise((resolve, reject) => {
// Bereits abgebrochen? Sofort ablehnen.
if (signal?.aborted) return reject(signal.reason);
const onAbort = () => {
clearTimeout(id);
reject(signal.reason);
};
const id = setTimeout(() => {
signal?.removeEventListener('abort', onAbort);
resolve('fertig');
}, ms);
signal?.addEventListener('abort', onAbort, { once: true });
});
const run = async () => {
try {
await sleep(5000, { signal: AbortSignal.timeout(100) });
} catch (err) {
console.log(err.name);
}
};
run();
Aufräumen bei abgebrochenem fetch
const controller = new AbortController();
const spinner = document.querySelector('#spinner');
controller.signal.addEventListener('abort', () => {
spinner.hidden = true;
console.log('Anfrage abgebrochen, UI zurückgesetzt');
}, { once: true });
document.querySelector('#cancel').onclick = () => controller.abort();
try {
spinner.hidden = false;
const res = await fetch('/api/report', { signal: controller.signal });
console.log(await res.json());
} catch (err) {
if (err.name !== 'AbortError') throw err;
}
// Wichtig · Fallstricke
- Kein nachträgliches Auslösen: Ist das Signal schon abgebrochen, wenn du den Listener registrierst, wird er nie aufgerufen. Prüfe deshalb vorher
signal.abortedoder rufesignal.throwIfAborted()auf. - Speicherlecks: Langlebige Signale, etwa ein globaler Controller, sammeln Listener an. Entferne sie mit
removeEventListener, wenn die Operation normal endet, und nutze{ once: true }. - Das Ereignis wird synchron innerhalb von
abort()ausgelöst. Code nachcontroller.abort()läuft also erst, wenn alle Handler durch sind. - Löst ein Handler eine Ausnahme aus, wird sie als nicht abgefangener Fehler gemeldet.
abort()selbst wirft dabei nicht. - Der Standardgrund ist eine
DOMExceptionmit dem NamenAbortError, beiAbortSignal.timeout()heißt erTimeoutError. - Kompatibilität:
abortundonabortgibt es in allen modernen Browsern.reason,timeout()undany()sind jünger (etwa 2022–2023), prüfe sie bei älteren Umgebungen. In Node.js istAbortSignalab Version 15 global verfügbar.