Signatur
Beschreibung
Die statische Methode AbortSignal.any() nimmt ein iterierbares Objekt (z. B. ein Array) von AbortSignal-Instanzen entgegen und gibt ein neues AbortSignal zurück. Dieses abhängige Signal wechselt in den abgebrochenen Zustand, sobald eines der übergebenen Signale abbricht. Sein reason ist dann der Abbruchgrund genau dieses ersten abgebrochenen Signals.
Typisch ist die Kombination verschiedener Abbruchquellen, etwa ein benutzergesteuerter Abbruch über einen AbortController und ein Zeitlimit über AbortSignal.timeout(). Früher musste man dafür Event-Listener von Hand verdrahten und später wieder aufräumen. AbortSignal.any() erledigt das sauber und ohne Speicherlecks.
Ist beim Aufruf bereits eines der Eingangssignale abgebrochen, ist auch das zurückgegebene Signal sofort abgebrochen. Es übernimmt dann den reason des ersten abgebrochenen Signals in der Reihenfolge der Iteration. Das kombinierte Signal lässt sich überall einsetzen, wo ein signal erwartet wird, zum Beispiel bei fetch(), addEventListener() oder bei Streams.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $iterable Pflicht | Iterable<AbortSignal> | Ein iterierbares Objekt, z. B. ein Array oder ein Set, das AbortSignal-Instanzen enthält. Ein leeres Iterable ist erlaubt und ergibt ein Signal, das nie abbricht. |
Rückgabewert
AbortSignal, das abbricht, sobald eines der Eingangssignale abbricht. Sein reason entspricht dem Grund dieses Signals. Ist bereits beim Aufruf ein Eingangssignal abgebrochen, ist auch das Rückgabesignal sofort abgebrochen.Beispiele
Fetch mit Benutzerabbruch und Zeitlimit
const controller = new AbortController();
document.querySelector('#cancel')?.addEventListener('click', () => controller.abort());
const loadData = async () => {
const signal = AbortSignal.any([
controller.signal, // Abbruch durch den Benutzer
AbortSignal.timeout(5000) // spätestens nach 5 Sekunden
]);
try {
const res = await fetch('/api/daten', { signal });
return await res.json();
} catch (err) {
if (err.name === 'TimeoutError') {
console.log('Zeitlimit überschritten');
} else if (err.name === 'AbortError') {
console.log('Vom Benutzer abgebrochen');
} else {
throw err;
}
}
};
loadData();
Abbruchgrund des ersten Signals wird übernommen
const a = new AbortController();
const b = new AbortController();
const combined = AbortSignal.any([a.signal, b.signal]);
combined.addEventListener('abort', () => {
console.log('Abgebrochen:', combined.reason);
});
b.abort('Grund B');
a.abort('Grund A'); // hat keine Wirkung mehr auf combined
console.log(combined.aborted);
Bereits abgebrochenes Eingangssignal
const done = AbortSignal.abort('schon erledigt');
const live = new AbortController();
const signal = AbortSignal.any([live.signal, done]);
console.log(signal.aborted, signal.reason);
Event-Listener an Komponenten- und Seitenlebensdauer koppeln
const pageController = new AbortController();
const mountWidget = (el) => {
const widgetController = new AbortController();
const signal = AbortSignal.any([pageController.signal, widgetController.signal]);
// Listener wird automatisch entfernt, wenn eines der Signale abbricht
window.addEventListener('resize', () => {
el.textContent = `Breite: ${window.innerWidth}px`;
}, { signal });
return () => widgetController.abort(); // Aufräumfunktion
};
const unmount = mountWidget(document.body);
// später: unmount(); oder pageController.abort();
// Wichtig · Fallstricke
- Browserunterstützung: Erst seit 2024 in allen großen Browsern verfügbar (Chrome/Edge 116, Firefox 124, Safari 17.4) und in Node.js ab 20.3. Für ältere Umgebungen per Feature-Erkennung prüfen:
if ('any' in AbortSignal) { … }. Andernfalls mit einem eigenenAbortControllerundabort-Listenern nachbauen. - Das Rückgabesignal ist unabhängig. Es hat keinen eigenen Controller, lässt sich also nicht direkt abbrechen. Wer es auch manuell abbrechen will, nimmt zusätzlich das Signal eines eigenen
AbortControllerin die Liste auf. - Der Abbruch wirkt nur in eine Richtung: Bricht das kombinierte Signal ab, bleiben die Eingangssignale unverändert.
- Welcher Fehler geworfen wird, hängt vom
reasonab.AbortSignal.timeout()führt zuTimeoutError,controller.abort()ohne Argument zuAbortError. Beim Fehlerhandling beide Fälle unterscheiden. - Wird ein Element übergeben, das kein
AbortSignalist, wirft die Methode einenTypeError. - Browser geben abhängige Signale frei, wenn sie nicht mehr gebraucht werden. Trotzdem sollte man in Schleifen keine unnötig vielen kombinierten Signale auf langlebigen Quellsignalen erzeugen.