AbortController - abort() Methhode
Die abort() Methode des AbortController ist ein zentraler Bestandteil moderner Webentwicklung, der präzise Kontrolle über asynchrone Prozesse ermöglicht. Diese Methode sendet ein Abbruchsignal an alle verbundenen Operationen, wodurch Netzwerkanfragen, Dateiübertragungen oder andere langläufige Prozesse elegant beendet werden können. Als effektives Werkzeug zur Ressourcenoptimierung verhindert sie unnötige Verarbeitung und trägt zu einer verbesserten Anwendungsperformance bei.
Inhaltsverzeichnis
Einführung
Die abort() Methode des AbortController wird aufgerufen, um das Abbruchsignal an alle Operationen zu senden, die das zugehörige AbortSignal beobachten.
Syntax
Die Syntax sieht wie folgt aus.
const controller = new AbortController();
controller.abort([reason]);Parameter
reason: (Optional) Ein beliebiger Wert, der angibt, warum die Operation abgebrochen wurde. Dieser Wert wird derreasonEigenschaft desAbortSignalObjekts zugewiesen und steht der abgebrochenen Operation zur Verfügung. Wenn nicht angegeben, ist derreasoneinDOMExceptionmit dem NamenAbortError.
Rückgabewert
undefined
Funktionsweise
Wenn abort() aufgerufen wird:
- Die
abortedEigenschaft des zugehörigenAbortSignalwird auftruegesetzt. - Das
abortErgebnis wird auf demAbortSignalausgelöst. Wenn einonabortHandler für das Signal registriert wurde, wird dieser ausgeführt. - Asynchrone Operationen, die dieses Signal beobachten (z.B. ein
fetchAufruf), werden abgebrochen. Typischerweise führt dies dazu, dass die Promise der Operation mit einemDOMExceptionnamesAbortErrorrejected wird.
Einmal abgebrochen, kann ein AbortSignal nicht “un-abgebrochen” werden. Um eine neue abbrechbare Operation zu starten, muss ein neuer AbortController erstellt werden.
Beispiel 1
In diesem Beispiel bauen wir eine einfache HTML-Datei auf, welche per JavaScript Daten laden soll. Dabei werden wir die abort() Methode verwenden, um eine Anfrage abzubrechen.
<!DOCTYPE html>
<html>
<head>
<title>AbortController - Einfaches Fetch-Beispiel</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<button id="fetch_button">Daten laden</button>
<button id="cancel_button">Laden abbrechen</button>
<div id="output"></div>
<script>
const buttonFetch = document.getElementById("fetch_button");
const buttonCancel = document.getElementById("cancel_button");
const outputContainer = document.getElementById("output");
let controller;
buttonFetch.addEventListener("click", async () => {
// Erstelle neuen AbortController
controller = new AbortController();
const signal = controller.signal;
outputContainer.textContent = "Lade Daten ...";
buttonCancel.disabled = false;
buttonFetch.disabled = true;
try {
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1?_delay=5000", { signal });
if (!response.ok) {
throw new Error(`HTTP-Fehler. Status: ${response.status}`);
}
const data = await response.json();
outputContainer.textContent = `Daten geladen: ${JSON.stringify(data)}`;
} catch (error) {
if (error.name === "AbortError") {
outputContainer.textContent = "Fetch-Anfrage wurde abgebrochen";
console.log("Fetch abgebrochen");
} else {
outputContainer.textContent = `Fehler beim Laden: ${error.message}`;
console.log("Fetch Fehler:", error);
}
} finally {
buttonCancel.disabled = true;
buttonFetch.disabled = false;
}
});
buttonCancel.addEventListener("click", () => {
if (controller) {
controller.abort();
console.log("Abbruch angefordert");
}
});
buttonCancel.disabled = true;
</script>
</body>
</html>Was haben wir als Ergebnis? Zwei Buttons im Browser und unseren Container, welcher verschiedene Zustände als Text ausgibt.
Wenn wir auf den Button “Daten laden” klicken und, während Daten geladen werden, auf den Button “Laden abbrechen” klicken, sehen wir dass unser Request abgebrochen wird.

Wenn wir den Request neustarten und diesen nicht abbrechen, werden die Daten regulär geladen.

Beispiel 2
Im nächsten Beispiel bauen wir eine HTML-Datei mit JavaScript auf, welche fetch Funktion (Fetch API) verwendet, um Anfragen mit einer bestimmten Verzögerung zu starten.
Wir verwenden Timeout und AbortController, um eine Anfrage abzubrechen, falls diese länger, als die übergebe Anzahl von Millisekunden dauert.
<!DOCTYPE html>
<html>
<head>
<title>AbortController - Beispiel 2</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Beispiel: Fetch von Daten mit Timeout</h1>
<p>Öffne die Entwicklertools, um die Ausgabe zu sehen.</p>
<script>
async function fetchDataWithTimeout(url, timeoutMilliseconds) {
const controller = new AbortController();
const signal = controller.signal;
const timeoutId = setTimeout(() => {
controller.abort(new Error("Timeout überschritten"));
}, timeoutMilliseconds);
try {
console.log(`Starte Fetch für: ${url}`);
const response = await fetch(url, { signal, cache: "no-store" });
// Wenn der Fetch erfolgreich war, bevor der Timeout eintritt
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP Fehler! Status: ${response.status}`);
}
const data = await response.json();
console.log("Daten erfolgreich geladen:", data);
return data;
} catch (error) {
if (error.name === "AbortError") {
console.log("Fetch abgebrochen");
console.log("Grund:", signal.reason);
} else {
console.log("Anderer Fehler:", error);
}
// Wichtig: clearTimeout auch im Fehlerfall,
// falls der Fehler nicht durch den Timeout ausgelöst wurde
// und der Timeout noch laufen könnte
clearTimeout(timeoutId);
throw error;
}
}
// Verwendung
fetchDataWithTimeout("https://dummyjson.com/products/?limit=10&delay=3000", 2000)
.then(data => console.log("Verarbeitet:", data))
.catch(error => console.log("Endgültiger Fehler im Aufrufer gefangen."));
fetchDataWithTimeout("https://dummyjson.com/posts/?limit=5&delay=1000", 2000)
.then(data => console.log("Verarbeitet (Album):", data))
.catch(error => console.log("Endgültiger Fehler im Aufrufer gefangen (Album)"));
</script>
</body>
</html>Wenn wir nun diese Datei im Browser öffnen und in die Konsole hineinschauen, werden wir feststellen, dass ein Request korrekt verarbeitet wurde und der andere in einen Fehler hineingelaufen ist.

Was passiert nun schrittweise in diesem Beispiel?
fetchDataWithTimeout("https://dummyjson.com/products/?limit=10&delay=3000", 2000)
fetchDataWithTimeout("https://dummyjson.com/posts/?limit=5&delay=1000", 2000)- Beide Requests laufen gleichzeitig an
- Timeout ist bei beiden 2000 ms (2 Sekunden)
- Verzögerungen
- Produkte: 3000 ms (3 Sekunden)
- Posts: 1000 ms (1 Sekunde)
Das sehen wir auch an den Logs.
Starte Fetch für: https://dummyjson.com/products/?limit=10&delay=3000
Starte Fetch für: https://dummyjson.com/posts/?limit=5&delay=1000Die nächsten Logs (3 und 4) zeigen, dass bestimmte Daten verarbeitet worden sind.
Daten erfolgreich geladen: {posts: Array(5), total: 251, skip: 0, limit: 5}
Verarbeitet (Posts): {posts: Array(5), total: 251, skip: 0, limit: 5}- Der
postsRequest mit 1s Verzögerung wird rechtzeitig fertig. - Im
tryBlock vonfetchDataWithTimeout:clearTimeoutwird aufgerufen, da Antwort rechtzeitig kamresponse.okisttrue- Die Daten werden erfolgreich geparst
- Das Ergebnis wird im
.then()des Aufrufers ausgegeben. - Keine Fehler, alles sauber.
Anderer Fehler: Error: Timeout überschritten
at beispiel_2.html:19:22- Der
productsRequest mit 3s Verzögerung überschreitet den Timeout von 2s. - Nach 2 Sekunden wird
controller.abort()aufgerufen. - Im
catchBlock der Funktion wird der Fehler erkannt, hier aber nicht alsAbortError, sondern als allgemeiner Fehler mit der NachrichtTimeout überschritten. - Dieser Fehler wird geloggt.
clearTimeoutwird trotzdem ausgeführt.- Fehler wird weitergeworfen (
throw error).
Endgültiger Fehler im Aufrufer gefangen.- Im
.catch()des Aufrufers wird der Fehler aus demproductsFetch gefangen. - Dort wird eine einfache Meldung ausgegeben.