Was ist der Unterschied zwischen:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return "bbb";
})
.then(function(result) {
console.log(result);
});
und das:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return Promise.resolve("bbb");
})
.then(function(result) {
console.log(result);
});
Ich frage, da ich ein anderes Verhalten erhalte. Verwenden des Dienstes Angular und $ http mit Verkettung von .then (). Ein bisschen zu viel Code, daher zuerst das obige Beispiel.
Die Regel lautet: Wenn die Funktion im Handler then
einen Wert zurückgibt, wird das Versprechen mit diesem Wert aufgelöst/abgelehnt, und wenn die Funktion ein Versprechen zurückgibt, geschieht die nächste Klausel then
Wird die then
-Klausel von das Versprechen sein, das die Funktion zurückgegeben hat , so fällt in diesem Fall das erste Beispiel durch die normale Folge der thens
und Gibt erwartungsgemäß Werte aus. Im zweiten Beispiel ist das Versprechungsobjekt, das zurückgegeben wird, wenn Sie Promise.resolve("bbb")
ausführen, das then
, das beim Verketten aufgerufen wird (in jeder Hinsicht). Die Art und Weise, wie es tatsächlich funktioniert, wird unten ausführlicher beschrieben.
Zitat aus den Versprechungen/A + spec:
Das Versprechensauflösungsverfahren ist eine abstrakte Operation, die als Eingabe ein Versprechen und einen Wert verwendet, die wir als
[[Resolve]](promise, x)
bezeichnen. Wennx
ein thenable ist, versucht es, unter der Annahme, dass den Zustandx
anzunehmen x verhält sich zumindest etwas wie ein Versprechen . Ansonsten erfüllt es das Versprechen mit dem Wertx
.Diese Behandlung von thenables ermöglicht die Interoperabilität von Versprechungsimplementierungen, sofern sie eine Promises/A + -kompatible then-Methode bereitstellen. Es ermöglicht Promises/A + -Implementierungen auch, nicht konforme Implementierungen mit vernünftigen Methoden zu „assimilieren“.
Das Wichtigste, was hier zu beachten ist, ist diese Zeile:
wenn
x
ein Versprechen ist, nehmen Sie seinen Zustand an [3.4]
Beide Beispiele sollten sich ungefähr gleich verhalten.
Ein Wert, der in einem then()
-Handler zurückgegeben wird, wird zum Auflösungswert des Versprechens, das von diesem then()
zurückgegeben wird. Wenn der in .then
zurückgegebene Wert ein Versprechen ist, übernimmt das von then()
zurückgegebene Versprechen den Status dieses Versprechens und löst/lehnt ab, genau wie das zurückgegebene Versprechen.
In Ihrem ersten Beispiel geben Sie "bbb"
im ersten then()
-Handler zurück, sodass "bbb"
an den nächsten then()
-Handler übergeben wird.
In Ihrem zweiten Beispiel geben Sie ein Versprechen zurück, das sofort mit dem Wert "bbb"
aufgelöst wird, sodass "bbb"
an den nächsten then()
-Handler übergeben wird. (Die Promise.resolve()
hier ist irrelevant).
Das Ergebnis ist dasselbe.
Wenn Sie uns ein Beispiel zeigen können, das tatsächlich ein anderes Verhalten aufweist, können wir Ihnen sagen, warum dies geschieht.
Einfach ausgedrückt, innerhalb einer then
-Handlerfunktion:
A) Wenn x
ein Wert ist (Zahl, Zeichenfolge usw.):
return x
entspricht return Promise.resolve(x)
throw x
entspricht return Promise.reject(x)
B) Wenn x
ein bereits erfülltes (nicht mehr ausstehendes) Versprechen ist:
return x
entspricht return Promise.resolve(x)
, wenn das Versprechen bereits erfüllt wurde.return x
entspricht return Promise.reject(x)
, wenn das Versprechen bereits abgelehnt wurde. C) Wenn x
ein ausstehendes Versprechen ist:
return x
gibt ein ausstehendes Versprechen zurück und wird beim nachfolgenden then
ausgewertet.Weitere Informationen zu diesem Thema finden Sie in den Promise.prototype.then () - Dokumenten .
Sie haben bereits eine gute formelle Antwort erhalten. Ich dachte, ich sollte eine kurze hinzufügen.
Die folgenden Dinge sind identisch mit Versprechen/A + Versprechen:
Promise.resolve
aufrufen (In Ihrem Angular Fall ist das $q.when
)new $q
.then
-Rückruf.Für ein Versprechen oder einen einfachen Wert X sind also alle folgenden Werte identisch:
Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });
Kein Wunder, dass die Versprechensspezifikation auf dem Promise Resolution Procedure basiert, das eine einfache Interoperation zwischen Bibliotheken (wie $ q und nativen Versprechungen) ermöglicht und Ihr Leben insgesamt erleichtert. Wann immer eine versprochene Lösung eintritt, erfolgt eine Lösung, die eine allgemeine Konsistenz schafft.