ES6 Promises/在多个 Promise 完成后调用一个函数(不能使用 Promises.all)[重复]

Posted

技术标签:

【中文标题】ES6 Promises/在多个 Promise 完成后调用一个函数(不能使用 Promises.all)[重复]【英文标题】:ES6 Promises/calling a function after multiple promises are fulfilled (can't use Promises.all) [duplicate] 【发布时间】:2016-08-23 17:20:55 【问题描述】:

我正在编写需要这些事件按此顺序发生的 javascript

    同时触发多个 API 调用 在所有调用完成并返回响应后,执行一行代码

听起来很简单,但棘手的部分是我不能使用 Promises.all() 因为我仍然希望在所有承诺都已实现(无论成功与否)之后执行该行代码。除非我误解了 Promises.all(),否则一次失败会导致代码行无法在 then() 中执行,而在 error() 中执行太快。

我很可能会遗漏一些明显的东西,但我能看到的唯一其他方法是将 API 调用承诺链接在一起,但这会导致不会一次全部触发它们。所以基本上我认为我需要一个不是“快速失败”的 Promises.all() 版本。

这样做的正确方法是什么?

【问题讨论】:

Promise.all() 如果多个promise有依赖关系,则将它们一个接一个地链接起来。因此,如果一个失败,它根本不会尝试其他的,并将返回到您的 catch()。如果您对拒绝案例(错误)有容忍度,那么您应该手动将您的 Promise 与 thens 和 catchs 链接起来,并通过它们的 catch() 处理被拒绝的操作,并从该 catch() 继续执行下一个 Promise。 不确定说它不会“尝试”其他的是否准确:当它们被传递给 Promise.all 时,它们都已经开始运行了。所以无论他们有什么行为,以及任何链接到每个单独的 .then/catch() 操作都将继续运行。 【参考方案1】:

要严格使用 ES6 Promise,您需要将每个 Promise 包装在另一个包装 Promise 中,当包装的 Promise 被履行或拒绝时,它会得到解决。

你可以这样做:

Promise.all( 
  promises.map( promise => Promise.resolve( promise ).catch( _=>_ ) )
).then ( function ( ) 
    // All promises finished
 );

这假定promises 是一组承诺和/或值。

【讨论】:

避免Promise constructor antipattern! @Bergi 我不认为它是一种反模式,因为它使事情更具可读性,但我对其进行了更新以避免使用 Promise 构造函数。 除了它没有,真的 :-) 顺便说一句,你可以进一步简化:.then(null, _=>_).catch(_=>_) 感谢 Bergi 和 Paulpro(以及 Dtipson),我是 Promise 的新手,仍然试图理解这里给出的答案,当我尝试我的实现时我会回复!抱歉重复的问题,我最初搜索答案时找不到该主题! 我能够使用您的答案,而且它似乎完全符合我的要求,再次感谢 Paulpro!【参考方案2】:

可能有比这更巧妙的方法,甚至是这种特定方法的更好的书面版本,但是您可以将行为链接到每个承诺(对于 then 和 catch,所以它不会使用 Promise.all)问题)更新主 Promise 中的值。

const allPromises = arrayOfPromises => Promise((resolve,reject)=> 
  const ln = arrayOfPromises.length,
        done = 0;

  const allDone => _ => 
    if(++done===ln) resolve(); 
  
  arrayOfPromises.map(p=>p.then(allDone).catch(allDone));
);

【讨论】:

以上是关于ES6 Promises/在多个 Promise 完成后调用一个函数(不能使用 Promises.all)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

原生 ES6 承诺中 Bluebird Promise.finally 的等价物是啥? [复制]

javascript 在系列#js #promise中运行Promises

javascript 在系列#js #promise中运行Promises

JavaScript Promises:将 Promise 与非 Promise 对象链接起来。为啥它有效?

具有多个处理程序的 Angular Promise

Promises/A+ 标准翻译