蓝鸟承诺加入行为

Udo*_*ein 10 javascript node.js promise bluebird

如果我用Node.js执行以下代码

var Promise = require('bluebird');

Promise.join(
    function A() { console.log("A"); },
    function B() { console.log("B"); }
).done(
    function done() { console.log("done");}
);
Run Code Online (Sandbox Code Playgroud)

控制台将记录

B
done
Run Code Online (Sandbox Code Playgroud)

不过我希望如此

A
B
done
Run Code Online (Sandbox Code Playgroud)

要么

B
A
done
Run Code Online (Sandbox Code Playgroud)

如果它在函数A中设置了断点,则永远不会达到.为什么它处理B但不处理A?

Ben*_*aum 16

Promise.join需要承诺其所有参数,但它的最后一个,这是一个功能.

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

您正在为它提供两个功能,因此它执行以下操作:

  • 做出承诺function A() { ... }- 基本上对它做出承诺
  • 当它完成(立即)执行最后一个参数,function B() {... }记录它.

查看文档:

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

用于协调多个并发离散承诺.虽然.all()适用于处理动态大小的统一promise的列表,但是当你有一些你希望同时协调的固定数量的离散promise时,Promise.join会更容易使用(并且性能更高),例如:

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

});


更新:

JSRishe 在这个答案中提出了另一种巧妙的方法来解决这种模式,它看起来像:

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

这是有效的,因为请求已经在延迟返回之前发生,因为在同一范围内调用该函数.

  • @jfriend00`Promise.join(p1,p2,...,pn,fn)`的行为类似于`Promise.all([p1,p2,...,pn]).spread(fn)`除了它稍快一些.这对于固定数量的promises很有用,并且使用promises作为代理是很好的糖:`var p1 = asyncOp(); var p2 = p1.then(otherOp); var p3 = p2.then(oneMore); Promise.join(p1,p2,p3,function(r1,r2,r3){...`.它的另一个优点是TypeScript等语言中更好的类型信息,因为它更容易静态分析. (5认同)