Start · Sprachen · JavaScript · Referenz · AbortSignal.throwIfAborted()

AbortSignal.throwIfAborted()

Methode

Wirft den Abbruch-Grund (<code>signal.reason</code>), wenn das Signal abgebrochen wurde. Andernfalls tut die Methode nichts.

seit JavaScript Baseline 2022: Chrome 100, Firefox 97, Safari 15.4 Kategorie: webapi

Signatur

AbortSignal.prototype.throwIfAborted()

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

Typ
void
Beschreibung
Gibt 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);
}
noch aktiv AbortError true

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);
}
Fehler: Vom Nutzer abgebrochen

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;
}
Zeitlimit überschritten (falls der Dienst innerhalb von 5 s nicht bereit ist)

// Wichtig · Fallstricke

  • Kein automatischer Abbruch: throwIfAborted() prüft nur zum Zeitpunkt des Aufrufs. Soll auch ein laufender Wartevorgang (z. B. ein setTimeout-Promise) sofort abbrechen, braucht man zusätzlich signal.addEventListener('abort', …, { once: true }).
  • Der geworfene Wert ist beliebig: Mit controller.abort('Text') wird ein String geworfen, kein Error. Prüft man err.name === 'AbortError', schlägt das dann fehl. Deshalb am besten immer Error-Objekte als Grund übergeben.
  • Fehler unterscheiden: Bei AbortSignal.timeout() heißt der Fehler "TimeoutError", nicht "AbortError". Im catch-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 auch signal.reason gibt es erst seit etwa derselben Zeit.
  • Bei optionalen Signalen den Aufruf mit signal?.throwIfAborted() absichern.