当非承诺引发错误时,为什么Promise.all不会拒绝?
根据MDN,
Promise.all() 方法将一个可迭代的 promise 作为输入,并返回一个解析为输入 promise 结果数组的单个 Promise。当所有输入的承诺都已解决,或者输入可迭代对象不包含承诺时,此返回的承诺将解决。它在任何输入承诺拒绝或非承诺抛出错误时立即拒绝,并且将拒绝此第一个拒绝消息/错误。
这是一个代码片段,它没有像我预期的那样按照上面的定义捕获错误:-
const promise1 = Promise.resolve(3);
const promise2 = () => {throw new Error('random error')};
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2(), promise3]).then((values) => {
console.log(values);
}).catch(e=>console.log('Error caught',e));
回答
因为错误是在调用之前抛出的Promise.all。Promise.all对你来说,把它转化为拒绝是不可能的。
您promise2在构建数组时调用,这发生在将该数组传递给Promise.all.
你的代码在这里:
Promise.all([promise1, promise2(), promise3])/*...*/
Promise.all([promise1, promise2(), promise3const x0 = promise1;
const x1 = promise2(); // <==== Error is thrown here
const x2 = promise3;
const array = [x0, x1, x2];
Promise.all(array)/*...*/
const x0 = promise1;
const x1 = promise2(); // <==== Error is thrown here
const x2 = promise3;
const array = [x0, x1, x2];
Promise.all(array)/*...*/
...等效于以下内容(变量除外):
要使其如您所愿,您有多种选择:
async正如TkoL在评论中指出的那样,您可以将其设为函数:
这是有效的,因为async函数总是返回承诺(即使您不使用await),并且异步函数中的错误拒绝它返回的承诺。
您可以制作promise2一个thenable以便它在then被调用之前不会抛出,然后Promise.all将其转换为拒绝: