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, wie ich ein anderes Verhalten bekomme. Verwenden des Angular- und $ http-Dienstes mit Verkettung .then (). Ein bisschen zu viel Code, daher zuerst das obige Beispiel.
javascript
angularjs
promise
q
Spirytus
quelle
quelle
Promise.resolve()
im zweiten Beispiel ist unnötig.then
daran, ein Versprechen von einem Handler zurückzugeben. Tatsächlich ist es ein Schlüsselaspekt der Versprechensspezifikation, dass Sie dies tun können.then
s funktioniert - der Begriff "andere Sprachen"then
lautet sowohl amap
als auch aflatMap
.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));
Dieser Code bleibt einfach hängen (nicht für immer gelöst). Aber wenn ichreturn "haha";
zureturn res("haha");
dann wechsle , wird es funktionieren und "haha" alarmieren. Hat der fetch (). Then () nicht schon "haha" in ein gelöstes Versprechen eingewickelt?Antworten:
Die Regel lautet: Wenn die im
then
Handler enthaltene Funktion einen Wert zurückgibt, wird das Versprechen mit diesem Wert aufgelöst / abgelehnt. Wenn die Funktion ein Versprechen zurückgibt, ist die nächstethen
Klausel diethen
Klausel des Versprechens, das die Funktion zurückgegeben hat In diesem Fall durchläuft das erste Beispiel die normale Reihenfolge derthens
und druckt Werte aus, wie zu erwarten ist. Im zweiten Beispiel wird das Versprechen-Objekt, das zurückgegeben wird, wenn Sie dies tunPromise.resolve("bbb")
,then
beim Verketten aufgerufen (im Grunde). Die Art und Weise, wie es tatsächlich funktioniert, wird unten ausführlicher beschrieben.Zitat aus der Promises / A + Spezifikation:
Das Wichtigste hier ist diese Zeile:
quelle
then
Handler ein Versprechen zurückgibt. +1 für die Spezifikationsreferenz.[[Resolve]]
sowohl aufthen
Fähigkeiten als auch auf Werten aufgerufen wird, so dass im Wesentlichen ein Wert mit dem Versprechen umhüllt wird, so dass erreturn "aaa"
derselbe istreturn Promise.resolve("aaa")
undreturn Promise.resolve("aaa")
derselbe ist wiereturn Promise.resolve(Promise.resolve("aaa"))
- da die Auflösung idempotent ist, ihn auf einen Wert mehr aufzurufen als einmal hat das gleiche Ergebnis."aaa"
und in jedem Fallreturn Promise.resolve("aaa")
inthen
Fähigkeiten austauschbar sind?In einfachen Worten, innerhalb eines
then
Handlerfunktion:A) Wann
x
ist ein Wert (Zahl, Zeichenfolge usw.):return x
ist äquivalent zureturn Promise.resolve(x)
throw x
ist äquivalent zureturn Promise.reject(x)
B) Wann
x
ist ein Versprechen bereits erfüllt (nicht mehr ausstehend):return x
ist äquivalent zureturn Promise.resolve(x)
, wenn das Versprechen bereits gelöst wurde.return x
ist gleichbedeutend mitreturn Promise.reject(x)
, wenn das Versprechen bereits abgelehnt wurde.C) Wann
x
steht ein Versprechen aus?return x
gibt ein ausstehendes Versprechen zurück und es wird im folgenden ausgewertetthen
.Weitere Informationen zu diesem Thema finden Sie in den Dokumenten Promise.prototype.then () .
quelle
Ihre beiden Beispiele sollten sich ziemlich gleich verhalten.
Ein in einem
then()
Handler zurückgegebener Wert wird zum Auflösungswert des von diesem zurückgegebenen Versprechensthen()
. Wenn der innerhalb von zurückgegebene Wert.then
ein Versprechen ist, wird das von zurückgegebene Versprechenthen()
den Zustand dieses Versprechens "annehmen" und genau wie das zurückgegebene Versprechen auflösen / ablehnen.In Ihrem ersten Beispiel kehren Sie
"bbb"
im erstenthen()
Handler zurück und werden"bbb"
an den nächstenthen()
Handler übergeben.In Ihrem zweiten Beispiel geben Sie ein Versprechen zurück, das sofort mit dem Wert aufgelöst
"bbb"
und"bbb"
an den nächstenthen()
Handler übergeben wird. (DasPromise.resolve()
hier ist irrelevant).Das Ergebnis ist das gleiche.
Wenn Sie uns ein Beispiel zeigen können, das tatsächlich ein anderes Verhalten zeigt, können wir Ihnen sagen, warum dies geschieht.
quelle
Promise.resolve();
vsreturn;
?undefined
statt"bbb"
.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
(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 identisch:
Und es ist keine Überraschung, dass die Versprechensspezifikation auf dem Versprechenslösungsverfahren basiert, das eine einfache Interaktion zwischen Bibliotheken (wie $ q und native Versprechungen) ermöglicht und Ihr Leben insgesamt erleichtert. Wann immer eine Versprechenslösung auftreten könnte, erfolgt eine Lösung, die eine allgemeine Konsistenz schafft.
quelle
Promise.resolve().then(function(){ return x; });
? Ich fand einen Ausschnitt, der etwas Ähnliches tat (es rief eine Funktion innerhalb desthen
Blocks auf). Ich dachte, es wäre mehr oder weniger wie eine Auszeit, aber es ist ein bisschen schneller. jsben.ch/HIfDowith
Block über einem Objekt oder Proxy mit einemx
Eigenschaftszugriff befinden, der eine Ausnahme auslöst. In diesem Fall würde Promise.resolve (x) einen ausgelösten Fehler verursachen,Promise.resolve().then(function(){ return x; });
wäre jedoch ein abgelehntes Versprechen, da der Fehler ausgelöst wird in athen
).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }
. Hier wird das Versprechen nicht vergeben. Worum geht es also? Eine Auszeit hätte (mehr oder weniger) den gleichen Effekt oder nicht?Der einzige Unterschied besteht darin, dass Sie dabei ein unnötiges Versprechen erstellen
return Promise.resolve("bbb")
. Wenn Sie ein Versprechen von einemonFulfilled()
Handler zurückgeben, wird die Lösung des Versprechens eingeleitet . So funktioniert die Verkettung von Versprechen .quelle