wake-up-neo.com

Was ist der Unterschied zwischen Rückgabewert oder Promise.resolve von dann ()

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.

284
spirytus

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. Wenn x ein thenable ist, versucht es, unter der Annahme, dass den Zustand x anzunehmen x verhält sich zumindest etwas wie ein Versprechen . Ansonsten erfüllt es das Versprechen mit dem Wert x.

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]

link: https://promisesaplus.com/#point-49

127
Hrishi

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.

87
JLRishe

Einfach ausgedrückt, innerhalb einer then -Handlerfunktion:

A) Wenn x ein Wert ist (Zahl, Zeichenfolge usw.):

  1. return x entspricht return Promise.resolve(x)
  2. throw x entspricht return Promise.reject(x)

B) Wenn x ein bereits erfülltes (nicht mehr ausstehendes) Versprechen ist:

  1. return x entspricht return Promise.resolve(x), wenn das Versprechen bereits erfüllt wurde.
  2. return x entspricht return Promise.reject(x), wenn das Versprechen bereits abgelehnt wurde.

C) Wenn x ein ausstehendes Versprechen ist:

  1. 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 .

81
Arian Acosta

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)
  • Aufruf des Versprechen-Konstruktors und Auflösen in seinem Resolver. In deinem Fall ist das new $q.
  • Rückgabe eines Wertes aus einem then -Rückruf.
  • Rufen Sie Promise.all in einem Array mit einem Wert auf und extrahieren Sie diesen Wert.

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.

49