2014-09-15 10 views
10

Se eseguo il seguente codice con Node.jsPromesse Bluebird Unisciti comportamento

var Promise = require('bluebird'); 

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

La console accedere

B 
done 

Tuttavia mi aspetterei

A 
B 
done 

o

B 
A 
done 

Se imposta un punto di interruzione nella funzione A non viene mai raggiunto. Perché è che elabora B ma non A?

risposta

16

Promise.join prende promesse come tutti i suoi argomenti ma il suo ultimo, che è una funzione.

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

Stai alimentandola due funzioni in modo che esegue le seguenti operazioni:

  • fare una promessa over function A() { ... } - in pratica il ritorno una promessa su di esso
  • Quando è fatto (immediatamente) eseguire l'ultimo argomento, function B() {... } registrarlo.

Vedere la documentazione:

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

di coordinare molteplici promesse discreti simultanei. Mentre .all() è utile per gestire un elenco di dimensioni dinamiche di promesse uniformi, Promise.join è molto più facile (e più performante) da utilizzare quando si dispone di una quantità fissa di promesse discreti che si desidera di coordinare contemporaneamente, ad esempio:

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

});


Aggiornamento:

JSRishe si avvicinò con un altro modo intelligente per risolvere questo tipo di modello in this answer che sembra qualcosa di simile:

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

Questo funziona perché la richiesta si verifica già prima che il ritardo ritorni poiché la funzione viene chiamata nello stesso ambito.

+1

C'è qualcosa '.join()' non può fare quello '.all()'? O è solo una sintassi diversa? – jfriend00

+5

@ jfriend00 'Promise.join (p1, p2, ..., pn, fn)' si comporta come 'Promise.all ([p1, p2, ..., pn]). Spread (fn)' eccetto che è leggermente più veloce . Questo è utile per un numero fisso di promesse ed è buono per l'utilizzo di promesse come proxy: 'var p1 = asyncOp(); var p2 = p1.then (otherOp); var p3 = p2.then (oneMore); Promise.join (p1, p2, p3, function (r1, r2, r3) {... '. L'altro vantaggio che ha è meglio digitare informazioni in linguaggi come TypeScript poiché è più semplice da analizzare staticamente. –