two people riding a bike, holding hands making promises
Webentwicklung |

Async-Abenteuer – oder: Wie ich lernte, Promises zu lieben (und nicht zu fürchten)

jessica.jpg.png

Jessica

9. April 2019

Hinweis: Dieser Artikel wurde unter Zuhilfenahme von KI aus dem Englischen übersetzt. Hier geht's zum Originaltext.

Lass uns über Promises und async/await in JavaScript sprechen. Bevor ich anfing zu verstehen, worum es bei Promises und async/await eigentlich geht, musste ich erst einmal Callbacks lernen. Das stellte sich als nicht ganz so spaßig heraus wie erhofft, besonders je tiefer ich in meine ganz persönliche Callback-Hölle abstieg. Zum Glück sagte mir jeder, ich solle mir keine Sorgen machen, im nächsten Schritt würde ich eine angenehmere Lösung kennenlernen – und innerlich begann der Song „I'm so excited" von den Pointer Sisters in meinem Kopf zu spielen. (Ein Lied, das ich wärmstens empfehlen kann!)

Promises — Mein persönlicher heiliger Gral

Man versuchte mir das mit Händen und Füßen zu erklären, aber für mich als JavaScript-Neuling waren Promises verwirrend und schwer zu verstehen. Ehrlich gesagt, erkannte ich anfangs nicht wirklich die Vorteile gegenüber Callbacks, aber mein Lernwille war zu groß, um aufzugeben. Also arbeitete ich mich durch zahlreiche Übungen zu Promises und mit jedem neuen Promise, das ich schrieb und verwendete, verstand ich mehr. Irgendwann dachte ich: „Hmm, vielleicht doch nicht so schlecht." Meine Begeisterung wuchs und nach einer Weile war mir (fast) alles klar.

Ein Promise kann drei Zustände haben: pending, rejected oder resolved.

  • Pending bedeutet, dass das Promise noch in Bearbeitung ist
  • Wenn ein Promise resolved ist, gibt es ein Promise-Objekt zurück, das mit einem bestimmten Wert oder einem als Wert übergebenen Promise aufgelöst wird
  • Ein rejected Promise gibt den Grund zurück, warum das Promise abgelehnt wurde

Ja, ab diesem Zeitpunkt hatte mich „Team Promises" völlig für sich gewonnen! Ich resolv-te und reject-ete wie ein Champion und verkettete alles, was ich finden konnte. Nichts war vor mir sicher. Nichts konnte mich aufhalten.

Lass mich die wichtigsten Vorteile meiner neuen besten Freunde erklären. Bleib dran, ich Promise dir, es wird sich lohnen! (haha, ich und meine Wortspiele...)

Im Vergleich zu Callbacks bieten Promises eine leserlichere Art, asynchronen Code zu schreiben. Du kannst deine Kette einfach lesen wie „Zuerst mache ich dies, dann das und dann jenes, ..." und so weiter. Und da haben wir das kleine magische Wort, das Promises viel verständlicher macht: „then". Die „then"-Methode verkettet weitere Promises nacheinander, so oft du willst, und gibt den zurückgegebenen Wert einer Funktion als Eingabe für die nächste weiter. Auch wenn es wie synchroner Code aussieht und sich so liest, schreibst du immer noch asynchronen Code. Yay, wie cool ist das denn?

Ist das nicht leicht zu lesen? Ja... ja, das ist es!

Und es wird noch besser: Die Fehlerbehandlung ist viel detaillierter.

Stellen wir uns vor, unser Promise von oben wird abgelehnt, weil eine Bedingung nicht erfüllt ist: Die catch()-Methode, die du überall in der Promise-Kette platzieren kannst, wird ausgelöst und gibt ein neues Promise zurück, das du behandeln kannst. Genau wie die then()-Methode kannst du die catch()-Methode so oft verwenden, wie du willst.

If you cannot handle Promises at their worst, you don't deserve them at their best.

Das hat mal irgendein JavaScript-Entwickler gesagt.

Der süße Geschmack des syntaktischen Zuckers

Es wird sogar noch besser. Du sagst: „Niemals!" – Ich sage: „await ✋" (haha, verstehst du?)

Wer ein Fan von syntaktischem Zucker ist, ist hier definitiv an der richtigen Stelle, denn meiner Meinung nach ist das der Hauptvorteil von async/await. Nehmen wir die Funktion von oben und schreiben sie mit async/await zur Erklärung neu.

Wie du siehst, beschreiben wir diese Funktion als asynchron, indem wir das Schlüsselwort „async" an den Anfang einer Funktion setzen (okay, das war offensichtlich...). Der try/catch-Block ist die alternative Schreibweise zu unserem resolve und reject von vorher.

  • try: Promise wird aufgelöst (resolved)
  • catch: Promise wird abgelehnt (rejected)

Erstellen wir also ein realistischeres Beispiel. Oft wollen wir Daten abrufen und dann entscheiden, was wir mit diesen Daten machen. Der Code könnte so aussehen:

Erinnert uns das nicht an eine Callback-Hölle? Mit async/await wirst du das Problem der Callback-Hölle los und musst dich nicht mehr mit endlosen verschachtelten Funktionen herumschlagen. Wir platzieren unsere Promises direkt in der Funktion und „await"-en ihre Ergebnisse. Aber Vorsicht, du darfst das „await"-Schlüsselwort nur innerhalb einer async-Funktion verwenden, top-level-await ist noch nicht möglich.

Die async/await-Version ist kompakter und lesbarer, weil wir nur zwei Einrückungsebenen haben im Vergleich zu den vier Ebenen der Funktion ohne async/await. Würde sagen: Syntaktischer Zucker vom Feinsten.

Jetzt, wo du diese süßen, süßen Köstlichkeiten probiert hast, denk daran, dir die Zähne zu putzen, Kinder!

Danke für die Aufmerksamkeit & bleibt asynchron.

Async/Await

JavaScript

Promises

Callbacks

Call Stack

Weitere Themen

Lea, 04.04.2025

Vue clever nutzen – Wiederverwendbarkeit für Einsteiger:innen

Vue

JavaScript

Reusability

DRY Principle

Components

Composables

Zum Blogartikel
Header-top-ten-mistakes-to-avoid.png

Francesca, Ricarda, 02.04.2025

Die 10 häufigsten Fehler bei der Entwicklung digitaler Produkte – und wie du sie vermeidest

MVP development

UX/UI design

product vision

agile process

user engagement

product development

Zum Blogartikel

Judith, 31.03.2025

Von der Hypothese zur echten Erkenntnis: MVPs richtig einsetzen

Zum Blogartikel