本文介绍了如何在没有“快速失败”行为的情况下等待多个并行承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 async / 等待来解雇几个 api 并行调用:

I'm using async/await to fire several api calls in parallel:

async function foo(arr) {
  const results = await Promise.all(arr.map(v => {
     return doAsyncThing(v)
  }))
  return results
}

我知道,不像循环 Promise.all (即等待结果部分)并行)。

I know that, unlike loops, Promise.all executes in-parallel (that is, the waiting-for-results portion is in parallel).

但:

当我读到这个时,如果我 Promise.all 有5个承诺,并且第一个完成返回 reject(),然后其他4个被有效取消,其承诺的 resolve()值将丢失。

As I read this, if I Promise.all with 5 promises, and the first one to finish returns a reject(), then the other 4 are effectively cancelled and their promised resolve() values are lost.

还有第三种方式吗?执行是否有效并行,但单一故障不会破坏整个群体?

Is there a third way? Where execution is effectively in-parallel, but a single failure doesn't spoil the whole bunch?

推荐答案

使用 catch 表示承诺结算(除非你抛出一个来自 catch 的异常或手动拒绝承诺链),因此您无需显式返回已解决的承诺IIUC。

Using catch means that the promise resolves (unless you throw an exception from the catch or manually reject the promise chain), so you do not need to explicitly return a resolved promise IIUC.

这意味着只需使用 catch 处理错误,就可以达到你想要的效果。

This means that simply by handling errors with catch you can achieve what you want.

如果你想要为了标准化拒绝处理方式,你可以对所有承诺应用拒绝处理功能。

If you want to standardize the way rejections are handled then you can apply a rejection handling function to all the promises.

async function bar() {
    await new Promise(r=> setTimeout(r, 1000))
      .then(()=> console.log('bar'))
      .then(()=> 'bar result');
}
async function bam() {
    await new Promise((ignore, reject)=> setTimeout(reject, 2000))
      .catch(()=> { console.log('bam errored'); throw 'bam'; });
}
async function bat() {
    await new Promise(r=> setTimeout(r, 3000))
      .then(()=> console.log('bat'))
      .then(()=> 'bat result');
}

function handleRejection(p) {
    return p.catch(err=> ({ error: err }));
}

async function foo(arr) {
  console.log('foo');
  return await Promise.all([bar(), bam(), bat()].map(handleRejection));
}

foo().then(results=> console.log('done', results));

这篇关于如何在没有“快速失败”行为的情况下等待多个并行承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 17:19