JavaScript/Objekte/Promise
Die mit ECMAScript 2015 (ES6) eingeführte Konstruktorfunktion Promise dient dazu, asynchrone Abläufe zu steuern und zu koordinieren. Ein solcher Vorgang wird durch eine Funktion eingeleitet, die der Promise-Konstruktor als Parameter erhält. Das Ergebnis ist über Callback-Funktionen abrufbar, die über die then-, catch und finally Methoden des Promise-Objekts registriert werden. Für den Einsatz in älteren Browsern steht ein Polyfill zur Verfügung (siehe Weblinks).
Dies ist eine Referenzseite. Zur Einführung lesen Sie bitte das Einführungstutorial zu Promises.
Konstruktor
var promise = new Promise(executor);
Concurrency-Methoden
Helfer-Methoden zum Erzeugen
Inhaltsverzeichnis
„Concurrency“ bedeutet nicht (unbedingt), dass Promises in einem Wettbewerb zueinander stehen. Gemeint ist, dass mehrere Promises gleichzeitig im schwebenden Zustand sind und man sie miteinander koordinieren muss.
Promises erzeugen
Die Promise-Konstrukturfunktion Promise dient zum einen als Träger für einige Helferfunktionen und kann zum anderen zusammen mit den new-Operator verwendet werden, um ein neues Promise zu erzeugen.
Per Konstruktor
Dazu ist der Konstruktorfunktion die so genannte Executor-Funktion zu übergeben. Diese führt die Aufgabe durch, deren Ergebnis mittels eines Promise bereitgestellt werden soll, und setzt abschließend das Promise in den Zustand fulfilled oder rejected, worauf der Nutzer des Promise dann mit Hilfe von Callbacks der then- und catch-Methoden oder mit Hilfe von await reagieren kann.
Damit die Executor-Funktion das Promise steuern kann, werden ihr vom Promise-Konstruktor zwei Funktionen übergeben. Diese werden üblicherweise als resolve und reject bezeichnet, aber es ist Dir überlassen, ob Du diese Namen verwendest oder andere nimmst.
Ein Beispiel zur Erstellung eines Promise mit Executor-Funktion findest Du im eingangs verlinkten Promise-Tutorial.
Durch Helferfunktionen
Mit Promise.resolve und Promise.reject lassen sich beliebige Werte in ein erfülltes oder zurückgewiesenes Promise „verpacken“. Das ist dann nützlich, wenn an irgendeiner Stelle im Programmcode ein Promise erwartet wird, man aber im Einzelfall nur den einfachen Wert verfügbar hat.
Seit 2024 ist es auch möglich, ein Promise ohne Executor-Funktion zu erzeugen. Siehe dazu die Beschreibung von Promise.withResolvers. Letztlich wird die Executor-Aufgabe dadurch lediglich an eine andere Stelle im Programm delegiert, oder im Zweifelsfall sogar durch das ganze Programm verstreut.
Und schließlich gibt es die Möglichkeit, dass man eine Funktion hat, die im Erfolgsfall einen Wert synchron zurückliefert und im Fehlerfall synchron einen Fehler wirft (throw). Aber vielleicht muss sie auch etwas asynchrones tun und liefert statt dessen ein Promise (Beispiel: ein Datencache). Man möchte das Ergebnis dieser Funktion aber einheitlich behandeln. Hier hilft Promise.try.
Subclassing
Du kannst von Promise eigene Subklassen ableiten. Soweit erforderlich, unterstützen Dich die Promise-Methoden dabei.
class Oath extends Promise {
constructor(executor) {
super(executor);
}
}
Der Zweck der Subklasse soll hier nicht diskutiert werden. Wichtig ist:
- Die geerbten statischen Methoden (z.B. all oder resolve) liefern keine Promise-Objekte, sondern Oath-Objekte zurück
- Promise.resolve reicht den übegebenen Wert nur dann 1:1 durch, wenn es sich um ein Oath-Objekt handelt
- .then, .catch und .finally geben Oath-Objekte zurück
Weblinks
- ECMA-Spezifikation: Promise Objects
- MDN Promise
- [1] Polyfill für ES6 Promises
- Lea Verou: Resolve Promises externally with this one weird trick vom 14.12.2016
- developers.google: JavaScript Promises: an Introduction von Jake Archibald
- Matt Greer: JavaScript Promises ... In Wicked Detail
deutsch:
- Peter Kroener: ECMAScript 6: Promises
- Wikipedia: Future (Programmierung)