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.
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)
. Six
est une thenable, il tente de faire une promesse adopte l'état dex
, en supposant que x se comporte au moins un peu comme une promesse . Sinon, il remplit la promesse avec la valeurx
.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]
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.
En termes simples, dans une fonction de gestionnaire then
:
A) Lorsque x
est une valeur (nombre, chaîne de caractères, etc.):
return x
est équivalent à return Promise.resolve(x)
throw x
est équivalent à return Promise.reject(x)
B) Lorsque x
est une promesse déjà réglée (non plus en attente):
return x
est équivalent à return Promise.resolve(x)
, si la promesse a déjà été résolue.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:
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 () .
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:
Promise.resolve
(Dans votre cas Angular c'est $q.when
)new $q
.then
.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.