2014-09-15 12 views
10

Wenn ich den folgenden Code mit Node.js ausführenDrossel Promises Registriert Verhalten

var Promise = require('bluebird'); 

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

Die Konsole

B 
done 

aber ich erwarten würde

A 
B 
done 

oder

loggt
B 
A 
done 

Wenn es einen Unterbrechungspunkt in Funktion A setzt, wird es nie erreicht. Warum verarbeitet es B, aber nicht A?

Antwort

16

Promise.join dauert verspricht wie alle seine Argumente, aber seine letzte, die eine Funktion ist.

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

Sie füttern es zwei Funktionen, so geschieht Folgendes:

  • ein Versprechen über function A() { ... } Make - im Grunde ein Versprechen über sie
  • Rückkehr Wenn es (sofort) ausführen, die zuletzt getan Argument, function B() {... } Protokollierung.

Lesen Sie die Dokumentation:

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

Für mehrere gleichzeitige diskrete Versprechen zu koordinieren. Während .all() ist gut für die Handhabung einer dynamisch großen Liste von einheitlichen Versprechen, Promise.Join ist viel einfacher (und mehr performant) zu verwenden, wenn Sie einen festen Betrag von diskreten Versprechungen, die Sie gleichzeitig koordinieren möchten, zum Beispiel:

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

});


Update:

JSRishe kam mit einem anderen cleveren Weg, bis diese Art von Muster zu lösen in this answer, die wie etwas aussieht:

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

Dies funktioniert, weil die Anforderung bereits vor dem Zurückkehren der Verzögerung erfolgt, da die Funktion im selben Bereich aufgerufen wird.

+1

Gibt es irgendwas '.join()' macht das '.all()' nicht? Oder ist es nur eine andere Syntax? – jfriend00

+5

@ jfriend00 'Promise.join (p1, p2, ..., pn, fn)' verhält sich wie 'Promise.all ([p1, p2, ..., pn]) .spread (fn)' außer es ist etwas schneller . Dies ist nützlich für eine feste Anzahl von Versprechen und ist ein guter Zucker, um Versprechungen als Proxies zu verwenden: 'var p1 = asyncOp(); var p2 = p1. dann (anderesOp); var p3 = p2.dann (oneMore); Promise.join (p1, p2, p3, Funktion (r1, r2, r3) {...}. Der andere Vorteil ist die bessere Typinformation in Sprachen wie TypeScript, da es einfacher ist, statisch zu analysieren. –