Simplifier les promesses en Javascript
-
21-12-2019 - |
Question
Les extraits de code suivants sont-ils équivalents ?
Version 1
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
Version 2
function doSomething() {
return foo().then(bar);
}
La solution
Il existe de nombreuses différences entre ces deux approches.
La principale différence entre les deux extraits est que dans version 2
vous transmettez implicitement la valeur résolue de foo
directement à bar
.En plus de ça doSomething
résoudra tout bar
se résoudra à, alors qu'en version 1
le résultat est rejeté.
Quelques points supplémentaires importants soulevés par Benjamin Gruenbaum :
(a) Si Bar est une erreur de référence 1 rejette la promesse intérieure et 2 lancers.
(b) 1 nécessite une référence à $ Q où 2 est la mise en œuvre agnostique.
(c) la version 1 n'est pas exceptionnellement sûre et un rejet sera avalé où la version 2 vous permettra de faire un rejet.;Il existe également plusieurs différences plus petites.Voir stackoverflow.com/questions/22539815
Vous pourriez aussi l'écrire comme ceci.
De cette façon, vous n'obtenez pas le passage implicite de la valeur résolue de foo
à bar
(c'est explicite maintenant), ce qui peut prêter à confusion ou facilement négligé.Cela peut également être utile si vous souhaitez faire quelque chose avec les valeurs résolues de foo
ou bar
avant de les retourner.
function doSomething() {
return foo().then(function(res){
// maybe do something with the result of foo
return bar(res);
}).then(function(res){
// maybe do something with the result of bar
return res;
});
}
La création manuelle d'un objet différé doit être réduite au minimum et constitue généralement un anti-modèle.
https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
Le principe clé démontré ici est qu'une promesse adoptera l'état de la promesse renvoyée ( ou thenable ) dans sa méthode de résolution.