Bluebird Promises Объединить поведение

Если я выполнил следующий код с Node.js

var Promise = require('bluebird');

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

Консоль будет записывать

B
done

Однако я ожидал бы

A
B
done

или

B
A
done

Если установить точку прерывания в функции A, она никогда не будет достигнута. Почему он обрабатывает B, но не A?

Ответ 1

Promise.join принимает promises как все его аргументы, но его последний, который является функцией.

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

Вы загружаете две функции, поэтому она делает следующее:

  • Сделать обещание над function A() { ... } - в основном вернуть обещание по нему
  • Когда это будет выполнено (немедленно), выполните последний аргумент, function B() {... } запустив его.

Смотрите документы:

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

Для координации нескольких параллельных дискретных promises. Хотя .all() хорош для обработки динамического размера унифицированного promises, Promise.join намного проще (и более результативно) использовать, когда у вас есть фиксированное количество дискретных promises, которые вы хотите координировать одновременно, например:

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 придумал еще один умный способ решить этот тип шаблона в этом ответе, который выглядит примерно так:

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

Это работает, потому что запрос уже выполняется до того, как задержка возвращается, поскольку функция вызывается в той же области.