Das Promise
Objekt stellt eine Repräsentation einer eventuellen Ausführung (oder eines Fehlschlags) einer asynchronen Operation und den daraus resultierenden Ergebnissen dar.
Um mehr darüber zu erfahren wie promises funktionieren und wie diese verwendet werden sollte zuerst Promises benutzen gelesen werden.
Beschreibung
Das Promise-Objekt (dt./deutsch Ein Versprechens-Objekt, das später eingelöst wird)
wird für asynchrone Berechnungen verwendet.
Ein Promise
kann sich in einem von drei Zuständen befinden:
- pending (schwebend): initialer Status, weder fulfilled noch rejected.
- fulfilled (erfüllt): heisst das die Operation erfolgreich abgeschlossen wurde.
- rejected (zurück gewiesen): heisst das die Operation gescheitert ist.
Ein weiterer Begriff beschreibt den Zustand settled (erledigt aber nicht zwingend erfolgreich): Der Promise ist entweder fulfilled oder rejected, aber nicht pending.
Syntax
new Promise(executor); new Promise(function(resolve, reject) { ... });
Parameter
- executor (Ausführer)
- Funktion mit den zwei Argumenten
resolve
undreject
. Das erste Argument führt den Promise aus, das zweite verwirft ihn. Die Funktionen können ausgeführt werden, sobald die Operation durchgeführt wurde.
Beschreibung
Das Promise
-Interface repräsentiert einen Proxy für einen Wert, der nicht zwingend bekannt ist, wenn der Promise erstellt wird. Das erlaubt die Assoziation zwischen Handler und dem Gelingen oder Fehlschlagen einer asynchronen Aktion. Mit diesem Mechanismus können asynchrone Methoden in gleicher Weise Werte zurück geben wie synchrone Methoden: Anstelle des endgültigen Wertes wird ein Promise zurückgegeben, dass es zu einem Zeitpunkt in der Zukunft einen Wert geben wird.
Ein Promise mit dem Status pending kann entweder zu fulfilled mit Wert oder zu einem rejected mit Grund werden. Wenn einer dieser Fälle eintritt, werden die assoziierten Handler, die über die then-Methode gequeued wurde, aufgerufen. Ist ein Promise bereits in fullfilled oder rejected und wird erst dann ein entsprechender Handler hinzugefügt, dann wird dieser Handler aufgerufen. Es gibt somit keine Race Conditions zwischen der Ausführung der asynchronen Aktion und dem Hinzufügen des Handlers.
Da die Methoden Promise.prototype.then
und Promise.prototype.catch
Promises zurückgeben, können sie aneinander gereiht werden (Komposition).
Properties
Promise.length
- Length-Attribut mit dem Wert 1 (Anzahl der Konstruktorargumente).
Promise.prototype
- Repräsentiert den Prototyp für den
Promise
-Konstruktor.
Methoden
Promise.all(iterable)
- Gibt einen
Promise
zurück, der aufgelöst wird, sobald alle Promises in demiterable
-Argument aufgelöst wurden. Promise.race(iterable)
- Gibt einen
Promise
zurück, der aufgelöst oder verworfen wird, sobald einer der Promises in demiterable
-Argument aufgelöst oder verworfen wurde, und den Wert oder den Grund dieses Promise enthält.
Promise.reject(reason)
- Gibt einen
Promise
zurück, der mit dem angegeben Grund (reason
) verworfen wird.
Promise.resolve(value)
- Gibt einen
Promise
zurück, der mitvalue
aufgelöst wird. Falls der Wert ein thenable ist (Objekt besitzt einethen
-Methode), folgt der zurückgegebenePromise
dem thenable und übernimmt den Status. Andernfalls wird der zurückgegebenePromise
auf fulfilled gesetzt.
Promise-Prototyp
Eigenschaften
Methoden
Beispiele
Einen Promise erstellen
Dieses kleine Beispiel zeigt den Mechanismus eines Promise
. Die Methode testPromise()
wird jedes Mal aufgerufen, wenn der <button>
geklickt wurde. Es wird ein Promise erstellt, der mithilfe von window.setTimeout
nach einer zufällig gewählten Zeit (1-3 s) zu 'result'
aufgelöst wird.
Die Ausführung der Promises wird mit einem fulfill-Callback unter Verwendung von p1.then
gelogt. Durch ein paar Logeinträge wird gezeigt, wie der synchrone Teil der Methode von der asynchronen Vollendung des Promises abgekoppelt ist.
var promiseCount = 0;
function testPromise() {
var thisPromiseCount = ++promiseCount;
var log = document.getElementById('log');
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Started (<small>Sync code started</small>)<br/>');
// Wir erstellen einen neuen Promise: wir versprechen den String 'result' (Wartezeit max. 3s)
var p1 = new Promise(
// Resolver-Funktion kann den Promise sowohl auflösen als auch verwerfen
// reject the promise
function(resolve, reject) {
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Promise started (<small>Async code started</small>)<br/>');
// nur ein Beispiel, wie Asynchronität erstellt werden kann
window.setTimeout(
function() {
// We fulfill the promise !
resolve(thisPromiseCount)
}, Math.random() * 2000 + 1000);
});
// wir bestimmen, was zu tun ist, wenn der Promise fulfilled
p1.then(
// Loggen der Nachricht und des Wertes
function(val) {
log.insertAdjacentHTML('beforeend', val +
') Promise fulfilled (<small>Async code terminated</small>)<br/>');
});
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Promise made (<small>Sync code terminated</small>)<br/>');
}
Dieses Beispiel wird ausgeführt, wenn der Button geklickt wird. Man benötigt einen Browser, der Promise unterstützt. Durch mehrmaliges Klicken in kurzer Zeit kann beobachtet werden, wie die einzelnen Promises nacheinander fulfilled werden.
Laden eines Bildes mit XHR
Ein weiteres, einfaches Beispiel für die Verwendung von Promises und XMLHTTPRequest,
um ein Bild zu laden, ist in dem MDN GitHub promise-test Repository. Hier kannst du es in Aktion sehen. Jeder Schritt ist kommentiert und erlaubt die den Promises und der XHR-Architektur nachzuvollziehen.
Spezifikationen
Spezifikation | Status | Kommentar |
---|---|---|
domenic/promises-unwrapping | Draft | Standardisierung findet hier statt. |
ECMAScript 2015 (6th Edition, ECMA-262) Die Definition von 'Promise' in dieser Spezifikation. |
Standard | Initiale Definition als ein ECMA-Standard. |
Browserkompatiblität
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic Support | 32 | 24.0 (24.0) als Future 25.0 (25.0) als Promise hinter einem Flag[1]29.0 (29.0) per Default |
Nicht unterstützt | 19 | 7.1 |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|
Basic Support | Nicht unterstützt | 24.0 (24.0) als Future 25.0 (25.0) als Promise hinter einem Flag[1]29.0 (29.0) per Default |
Nicht unterstützt | Nicht unterstützt | iOS 8 | 32 |
[1] Gecko 24 hat eine experimentelle Implementierung von Promises unter dem vorherigen Namen Future. In Gecko 25 wurde sie in ihren endgültigen Namen umbenannt, wird aber per Default durch das Flag dom.promise.enable
unterdrückt. Bug 918806 aktiviert Promises per Default in Gecko 29.
Siehe auch
- Promises/A+ specification
- Jake Archibald: JavaScript Promises: There and Back Again
- Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patter in JavaScript
- Matt Greer: JavaScript Promises ... In Wicked Detail
- Forbes Lindesay: promisejs.org
- Fussnote1: bitte die englischen Begriffe in dieser Übersetzung stehen lassen, da sonst der Zusammenhang zu englischen Dokumentation völlig verloren geht. Worte wie 'Promise' sollte man sich merken, um sie auch in englisch zu verstehen.