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 demande car j'obtiens un comportement différent Utilisation du service Angular et $ http avec le chaînage .then (). Un peu trop de code, donc d'abord l'exemple ci-dessus.
javascript
angularjs
promise
q
spirytus
la source
la source
Promise.resolve()
deuxième exemple n'est pas nécessaire.then
gestionnaire, en fait, c'est un aspect clé de la promesse que vous pouvez le faire.then
s imbriqués arbitrairement - le terme «autres langues» pour celathen
est à la fois amap
et aflatMap
.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));
ce code va juste se bloquer (pas résolu pour toujours). Mais si je passereturn "haha";
àreturn res("haha");
alors cela fonctionnera et alertera "haha". Le fetch (). Then () n'a-t-il pas déjà enveloppé "haha" dans une promesse résolue?Réponses:
La règle est, si la fonction qui se trouve dans le
then
gestionnaire renvoie une valeur, la promesse se résout / rejette avec cette valeur, et si la fonction renvoie une promesse, ce qui se passe, lathen
clause suivante sera lathen
clause de la promesse que la fonction a renvoyée , donc, dans ce cas, le premier exemple passe par la séquence normale dethens
et imprime les valeurs comme on pourrait s'y attendre, dans le deuxième exemple, l'objet de promesse qui est renvoyé lorsque vous le faitesPromise.resolve("bbb")
est alors celuithen
qui est invoqué lors du chaînage (à toutes fins utiles). La façon dont cela fonctionne est décrite ci-dessous plus en détail.Citant des promesses / A + spec:
La chose clé à noter ici est cette ligne:
la source
then
gestionnaire renvoie une promesse. +1 pour la référence de spécification.[[Resolve]]
on appelle à la fois sur lesthen
capacités et sur les valeurs, donc elle englobe une valeur avec la promessereturn "aaa"
est donc la même quereturn Promise.resolve("aaa")
etreturn Promise.resolve("aaa")
est la même quereturn Promise.resolve(Promise.resolve("aaa"))
- puisque la résolution est idempotente en l'appelant sur une valeur plus qu'une fois a le même résultat."aaa"
etreturn Promise.resolve("aaa")
sont interchangeables dans lesthen
capacités dans tous les cas?En termes simples, à l'intérieur d'une
then
fonction de gestionnaire:A) Quand
x
est une valeur (nombre, chaîne, etc.):return x
est équivalent àreturn Promise.resolve(x)
throw x
est équivalent àreturn Promise.reject(x)
B) Quand
x
une promesse est-elle déjà réglée (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) Quand
x
une promesse est-elle en attente:return x
renverra une promesse en attente, et elle sera évaluée lors de la suivantethen
.En savoir plus sur ce sujet dans les documents Promise.prototype.then () .
la source
Vos deux exemples devraient se comporter à peu près de la même manière.
Une valeur renvoyée à l'intérieur d'un
then()
gestionnaire devient la valeur de résolution de la promesse retournée à partir de celathen()
. Si la valeur renvoyée à l'intérieur de la.then
est une promesse, la promesse retournée parthen()
"adoptera l'état" de cette promesse et résoudra / rejetera tout comme la promesse retournée.Dans votre premier exemple, vous revenez
"bbb"
dans le premierthen()
gestionnaire, donc"bbb"
est passé dans lethen()
gestionnaire suivant .Dans votre deuxième exemple, vous renvoyez une promesse qui est immédiatement résolue avec la valeur
"bbb"
et"bbb"
est donc transmise authen()
gestionnaire suivant . (L'Promise.resolve()
ici est étranger).Le résultat est le même.
Si vous pouvez nous montrer un exemple qui présente en fait un comportement différent, nous pouvons vous expliquer pourquoi cela se produit.
la source
Promise.resolve();
vsreturn;
?undefined
au lieu de"bbb"
.Vous avez déjà une bonne réponse formelle. J'ai pensé que je devrais en ajouter un court.
Les choses suivantes sont identiques aux promesses / promesses A + :
Promise.resolve
(dans votre cas angulaire c'est$q.when
)new $q
.then
rappel.Ainsi, les éléments suivants sont tous identiques pour une promesse ou une valeur simple X:
Et ce n'est pas surprenant, la spécification des promesses est basée sur la procédure de résolution des promesses qui permet une interaction facile entre les bibliothèques (comme $ q et les promesses natives) et vous facilite la vie dans l'ensemble. Chaque fois qu'une résolution de promesse peut se produire, une résolution se produit, créant une cohérence globale.
la source
Promise.resolve().then(function(){ return x; });
? J'ai trouvé un snipping faisant quelque chose de similaire (il a appelé une fonction à l'intérieur duthen
bloc). Je pensais que c'était plus ou moins comme faire un timeout, mais c'est un peu plus rapide. jsben.ch/HIfDowith
bloc sur un objet ou un proxy avec unx
accesseur de propriété qui lève une exception. Dans ce cas, Promise.resolve (x) provoquerait une erreur levée maisPromise.resolve().then(function(){ return x; });
serait une promesse rejetée puisque l'erreur est levée en athen
).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }
. Ici, la promesse n'est pas attribuée, alors à quoi ça sert? Un timeout aurait (plus ou moins) le même effet, ou pas?La seule différence est que vous créez une promesse inutile lorsque vous le faites
return Promise.resolve("bbb")
. Le renvoi d'une promesse d'unonFulfilled()
gestionnaire démarre la résolution de la promesse . Voilà comment fonctionne le chaînage des promesses .la source