Promises, async/await und die fetch API mit einer schrittweisen Event-Loop-Zeitleiste und 15 Beispielen, die du bearbeiten und ausführen kannst: JSON, Formulare, Fehler, parallele Requests, AbortController und Retry.
Ein Promise steht für ein Ergebnis, das später eintrifft. async-Funktionen geben Promises zurück, und await pausiert diese Funktion, bis eines erledigt ist. fetch(url) gibt ein Promise auf eine Response zurück: Prüfe response.ok und dann await response.json(). Pack awaits in try und catch, nutze Promise.all für parallele Requests und AbortController zum Abbrechen.
Das Muster, das die meisten Seiten brauchen
Beginne mit der Zeitleiste, um zu sehen, warum Code nach einem await vor diesem laufen kann. Bearbeite dann ein beliebiges Beispiel, und es läuft sofort neu. Die Requests hier nutzen data:-URLs oder simulierte Server, sodass nichts deinen Browser verlässt.
Im Funktionsumfang keiner: async/await baut auf Promises auf. Eine async-Funktion gibt immer ein Promise zurück, und await packt eines aus. Es liest sich wie normaler Schritt-für-Schritt-Code, wodurch sich Fehler leichter mit try und catch behandeln lassen.
fetch behandelt jede HTTP-Antwort als erfolgreichen Request, denn der Server hat ja geantwortet. Es lehnt nur bei Netzwerkfehlern oder einem abgebrochenen Request ab. Prüfe response.ok oder response.status selbst.
Promise-Callbacks landen in der Microtask-Queue, die nach dem aktuellen Skript vollständig geleert wird. Ein Timer-Callback ist ein Task, der auf die nächste Runde des Event Loops wartet.
Erstelle einen AbortController, übergib controller.signal in den fetch-Optionen und rufe controller.abort() auf. Das fetch-Promise wird mit einem Fehler namens AbortError abgelehnt.
Ja, in JavaScript-Modulen (script type="module" oder jedes gebündelte ES-Modul). In klassischen Skripten packst du den Code in eine async-Funktion.
Synchrone Zeilen laufen zuerst, dann jeder wartende Promise-Callback (Microtasks), dann der Timer (ein Task). Ändere die Reihenfolge und führe es erneut aus.
Ein Promise wird genau einmal erledigt: resolve liefert einen Wert, reject einen Fehler. then und catch laufen später, nie sofort.
await pausiert nur die async-Funktion, in der es steht. Die Zeile nach dem Aufruf von main() läuft, bevor main fertig ist.
In einer async-Funktion wirft ein abgelehntes await einen Fehler, also funktionieren ganz normale try und catch. finally ist der Ort, um einen Spinner auszublenden.
fetch gibt eine Response zurück; .json() liest und parst den Body, was ein zweites await ist. Dieses Beispiel nutzt eine data:-URL und funktioniert daher offline.
fetch lehnt nur ab, wenn der Request gar nicht ausgeführt werden kann (offline, blockiert, ungültige URL). Ein 404 oder 500 wird normal aufgelöst, mit ok auf false, also prüfe es immer.
FormData liest jedes benannte Feld. Hier wird der Request gebaut, aber nicht gesendet, und sein Body wird ausgegeben, damit du genau siehst, was ein Server bekäme.
Sende JSON, indem du es in einen String umwandelst und den Content-Type-Header selbst setzt; fetch erledigt beides bei einfachen Objekten nicht.
Welchen Promise-Helfer du nutzen solltest
Wartest du auf einen Aufruf nach dem anderen, addieren sich die Wartezeiten. Startest du alle und wartest auf Promise.all, dauert es nur so lange wie der langsamste.
Promise.all lehnt ab, sobald einer fehlschlägt. allSettled wartet auf alle und sagt dir, welche funktioniert haben, was zu Dashboards mit unabhängigen Widgets passt.
Hunderte Requests auf einmal abzufeuern kann Rate Limits auslösen. Dieser kleine Pool hält höchstens drei gleichzeitig am Laufen.
Übergib controller.signal an fetch und rufe abort() auf, um es zu stoppen. Das Promise wird mit einem AbortError abgelehnt, den du meist ignorierst.
AbortSignal.timeout(ms) erzeugt ein Signal, das von selbst abbricht. Bei fetch heißt der Fehler TimeoutError, sodass du ihn von einem Abbruch durch den Nutzer unterscheiden kannst.
Wiederhole nur Fehler, die vorübergehen können, etwa einen Timeout oder einen 503, und warte jedes Mal länger, damit sich ein überlasteter Server erholen kann.
Warte auf eine Tipppause und brich den vorherigen Request ab, wenn ein neuer startet, damit eine alte, langsame Antwort nie eine neuere überschreiben kann.
Hast du eine Antwort, die du lesen musst? Füge sie ein in den
Call Stack
Microtasks
Task-Queue
Konsole
Schritt {i} von {n}.
Zurück
Nächster Schritt
Pause
Abspielen
Zurücksetzen
Kostenlos starten · Keine Kreditkarte nötig