2014-09-15 4 views
10

Si j'exécute le code suivant avec Node.jspromesses Bluebird Rejoignez le comportement

var Promise = require('bluebird'); 

Promise.join(
    function A() { console.log("A"); }, 
    function B() { console.log("B"); } 
).done(
    function done() { console.log("done");} 
); 

La console se connectera

B 
done 

Cependant, je me attends

A 
B 
done 

ou

B 
A 
done 

S'il définit un point d'arrêt dans la fonction A, il n'est jamais atteint. Pourquoi est-ce qu'il traite B mais pas A?

Répondre

16

Promise.join prend promet comme tous ses arguments mais son dernier, qui est une fonction.

Promise.join(Promise.delay(100), request("http://...com"), function(_, res){ 
     // 100 ms have passed and the request has returned. 
}); 

Vous nourrir deux fonctions il effectue les opérations suivantes:

  • Faire une promesse sur function A() { ... } - essentiellement retourner une promesse dessus
  • Une fois terminé (immédiatement) Donnent la dernière argument, function B() {... } l'enregistrant.

Voir les docs:

Promise.join(Promise|Thenable|value promises..., Function handler) -> Promise

Pour coordonner plusieurs promesses discrètes simultanées. Alors que .all() est bon pour gérer une liste dynamique de promesses uniformes, Promise.rejoindre est beaucoup plus facile (et plus performant) à utiliser lorsque vous avez un montant fixe de promesses discrètes que vous souhaitez simultanément coordonner, par exemple:

var Promise = require("bluebird");

var join = Promise.join;

join(getPictures(), getComments(), getTweets(),

          function(pictures, comments, tweets) {

          console.log("in total: " + pictures.length + comments.length + tweets.length);

});


Mise à jour:

JSRishe est venu avec une autre façon intelligente de résoudre ce genre de modèle in this answer qui ressemble à:

Promise.delay(100).return(request("http://...com").then(function(res){ 
    // 100 ms have passed and the request has returned 
}); 

Cela fonctionne parce que la demande se produit déjà avant le retour du délai puisque la fonction est appelée dans la même portée.

+1

Y a-t-il quelque chose '.join()' est ce que '.all()' ne peut pas faire? Ou est-ce juste une syntaxe différente? – jfriend00

+5

@ jfriend00 'Promise.join (p1, p2, ..., pn, fn)' se comporte comme 'Promise.all ([p1, p2, ..., pn]). Spread (fn)' sauf qu'il est légèrement plus rapide . Ceci est utile pour un nombre fixe de promesses et il est bon d'utiliser des promesses comme proxy: 'var p1 = asyncOp(); var p2 = p1.then (autreOp); var p3 = p2.then (unMore); Promise.join (p1, p2, p3, fonction (r1, r2, r3) {... '. L'autre avantage est de mieux taper des informations dans des langages comme TypeScript, car il est plus facile d'analyser statiquement. –

Questions connexes