如何处理异步函数内的异步承诺拒绝

时间:2020-11-08 18:37:17

标签: javascript asynchronous async-await

我有一个异步函数,如下所示:

async function foo() {
  const promises = [];

  for await (const value of asyncIterable) {
    promises.push( doSomething(value) ); // `doSomething` returns a promise.
  }

  await Promise.all(promises);
}

目标是将doSomething与每个value一起使用,但是存在一个问题:如果doSomething()返回的诺言在迭代器结束之前被拒绝,则拒绝不会被处理,因为async function尚未达到await Promise.all(promises);。我的目标是使其在任何promises拒绝时,由async function拒绝返回的承诺(就像使用同步迭代器一样)。 (如果doSomething()返回的承诺在迭代器结束后被拒绝,则Promise.all()将捕获拒绝,这将使Promise.all()返回的承诺被拒绝,并且由于异步函数await已实现该承诺,因此它将抛出。)

我能想到的唯一(好的)解决方案是:

/**
 * @param {Promise} p
 * @param {Promise[]} array
 * @returns {Promise} A promise that resolves with the value of `p` when it resolves
 * or rejects when any of the promises reject with the respective value
 */
function join(p, array) {
    return new Promise((res, rej) => {
        p.then(res, rej);
        for (const promise of array)
            promise.catch(rej);
    });
}

async function foo() {
  const promises = [];

  const asyncIterator = asyncIterable[Symbol.asyncIterator]
  let value, done;
  while (true) {
    ({ value, done } = await join(asyncIterator.next(), promises));
    if (done)
      break;
    promises.push( doSomething(value) ); // `doSomething` returns a promise.
  }

  await Promise.all(promises);
}

如您所见,它不是很优雅。有没有更好的方法来达到相同的结果?

0 个答案:

没有答案