web-dev-qa-db-fra.com

Quelle est la différence entre renvoyer une valeur ou Promise.resolve from then ()

Quelle est la différence entre:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });

et ça:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

Je pose la question alors que j'obtiens un comportement différent. Utiliser Angular et le service $ http avec chaînage .then (). Un peu trop de code donc d’abord l’exemple ci-dessus.

284
spirytus

La règle est la suivante: si la fonction qui se trouve dans le gestionnaire then renvoie une valeur, la promesse est résolue/rejetée avec cette valeur, et si la fonction renvoie une promesse, la prochaine clause then sera renvoyée. sera la clause then de la promesse que la fonction a renvoyée , de sorte que, dans ce cas, le premier exemple passe par la séquence normale de la thens et affiche les valeurs comme on pourrait s'y attendre. Dans le deuxième exemple, l'objet de promesse qui est renvoyé lorsque vous faites Promise.resolve("bbb") est alors le then qui est appelé lors de l'enchaînement (à toutes fins utiles). Son fonctionnement est décrit plus en détail ci-dessous.

Citant les spécifications Promises/A +:

La procédure de résolution de promesse est une opération abstraite prenant en entrée une promesse et une valeur, que nous appelons [[Resolve]](promise, x). Si x est une thenable, il tente de faire une promesse adopte l'état de x, en supposant que x se comporte au moins un peu comme une promesse . Sinon, il remplit la promesse avec la valeur x.

Ce traitement de thenables permet l’interopérabilité des implémentations de promesse, à condition qu’elles exposent ensuite une méthode conforme à Promises/A +. Cela permet également aux implémentations de Promises/A + d'assimiler des implémentations non conformes avec des méthodes raisonnables.

La chose clé à noter ici est cette ligne:

si x est une promesse, adopte son état [3.4]

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

127
Hrishi

Vos deux exemples devraient se comporter à peu près de la même façon.

Une valeur renvoyée dans un gestionnaire then() devient la valeur de résolution de la promesse renvoyée par cette then(). Si la valeur renvoyée à l'intérieur de .then est une promesse, la promesse renvoyée par then() "adoptera l'état" de cette promesse et sera résolue/rejetée de la même manière que la promesse retournée.

Dans votre premier exemple, vous renvoyez "bbb" dans le premier gestionnaire then(), de sorte que "bbb" est transmis au gestionnaire suivant then().

Dans votre deuxième exemple, vous retournez une promesse immédiatement résolue avec la valeur "bbb", de sorte que "bbb" est transmis au prochain gestionnaire then(). (La Promise.resolve() ici est étrangère).

Le résultat est le même.

Si vous pouvez nous montrer un exemple présentant un comportement différent, nous pouvons vous expliquer pourquoi.

87
JLRishe

En termes simples, dans une fonction de gestionnaire then:

A) Lorsque x est une valeur (nombre, chaîne de caractères, etc.):

  1. return x est équivalent à return Promise.resolve(x)
  2. throw x est équivalent à return Promise.reject(x)

B) Lorsque x est une promesse déjà réglée (non plus en attente):

  1. return x est équivalent à return Promise.resolve(x), si la promesse a déjà été résolue.
  2. return x est équivalent à return Promise.reject(x), si la promesse a déjà été rejetée.

C) Lorsque x est une promesse en attente:

  1. return x renverra une promesse en attente et sera évaluée sur la suivante then.

En savoir plus sur ce sujet sur les docs Promise.prototype.then () .

81
Arian Acosta

Vous avez déjà une bonne réponse formelle. J'ai pensé que je devrais ajouter un court.

Les choses suivantes sont identiques à Promises/A + promesses:

  • Appel de Promise.resolve (Dans votre cas Angular c'est $q.when)
  • Appel du constructeur de promesse et résolution dans son résolveur. Dans votre cas, c'est new $q.
  • Renvoyer une valeur à partir d'un rappel then.
  • Appeler Promise.all sur un tableau avec une valeur, puis extraire cette valeur.

Donc, les éléments suivants sont tous identiques pour une promesse ou une valeur simple X:

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]; });

Et il n’est pas surprenant que la spécification de promesses soit basée sur la Promise Resolution Procedure , qui permet une interopération facile entre les bibliothèques (comme $ q et les promesses natives) et vous facilite la vie dans son ensemble. Chaque fois qu'une résolution de promesse peut survenir, une résolution se produit, créant une cohérence globale.

49
Benjamin Gruenbaum