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

cle*_*ong 9 javascript node.js promise bluebird

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

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

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

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

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

Ben*_*aum 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
});
Run Code Online (Sandbox Code Playgroud)

它更快

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

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


Ber*_*rgi 5

您还可以将处理程序作为最后一个参数传递。我很好奇这个选项存在背后的基本原理。

这不是一个“选项”。这是该join功能的唯一目的。

Promise.join(promiseA, promiseB, …, function(a, b, …) { … })
Run Code Online (Sandbox Code Playgroud)

完全等同于

Promise.all([promiseA, promiseB, …]).spread(function(a, b, …) { … })
Run Code Online (Sandbox Code Playgroud)

但是,正如文档中所述,它

当您有固定数量的离散承诺时,使用起来更容易(也更高效)

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

  • @cleong 您正在使用已弃用的 join 版本,该版本仅因向后兼容而有效,新代码应仅使用新版本 (2认同)