我有一个异步函数,如下所示:
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);
}
如您所见,它不是很优雅。有没有更好的方法来达到相同的结果?