为什么promise.join()将函数作为其最后一个参数?

时间:2015-04-13 16:27:16

标签: javascript node.js promise bluebird

假设我在需要检索两个对象的过程中有一个步骤。我会使用join()来协调检索:

return promise.join(retrieveA(), retrieveB())
           .spread(function(A, B) {
               // create something out of A and B
           });

文档显示您还可以将处理程序作为最后一个参数传递:

return promise.join(retrieveA(), retrieveB(), function(A, B) {
           // create something out of A and B
       });

我很好奇这个选项存在的理由是什么。

2 个答案:

答案 0 :(得分:12)

事实时间:添加.join的原因是让@spion满意。不过没有理由,使用.join意味着你有一个静态和已知的数量的promise,这使得使用TypeScript更加容易。佩特卡(Esailija)喜欢这个想法以及它可以进一步优化的事实,因为它不必遵守其他形式必须遵守的奇怪保证。

随着时间的推移,人们开始(至少我)将其用于其他用例 - 即使用promises作为代理。

所以,让我们谈谈它做得更好:

静态分析

很难对Promise.all进行静态分析,因为它适用于具有潜在不同类型的未知类型承诺的数组。 Promise.join可以输入,因为它可以被视为取一个元组 - 所以例如对于3个承诺的情况,你可以给它一个(Promise<S>, Promise<U>, Promise<T>, ((S,U,T) -> Promise<K> | K)) -> Promise<K>的类型签名,这在类型安全中根本无法完成Promise.all的方式。

代理功能

以代理方式编写承诺代码时使用非常干净:

var user = getUser();
var comments = user.then(getComments);
var related = Promise.join(user, comments, getRelated);
Promise.join(user, comments, related, (user, comments, related) => {
     // use all 3 here
});

它更快

由于它不需要生成缓存的给定promises的值并保持所有检查.all(...).spread(...) - 它的执行速度会稍快。

但是......你真的通常不应该在意。

答案 1 :(得分:4)

  

您也可以将处理程序作为最后一个参数传递。我很好奇这个选项存在的理由是什么。

这不是&#34;选项&#34;。这是join功能的唯一目的。

Promise.join(promiseA, promiseB, …, function(a, b, …) { … })

完全等同于

Promise.all([promiseA, promiseB, …]).spread(function(a, b, …) { … })

但是,正如documentation中提到的那样,

  当您拥有固定数量的离散承诺时,

更容易使用(且性能更高)

它使您无需使用该数组文字,并且它不需要为数组结果创建该中间promise对象。