当非承诺引发错误时,为什么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.allPromise.all对你来说,把它转化为拒绝是不可能的。

promise2在构建数组时调用,这发生在将该数组传递给Promise.all.

你的代码在这里:

Promise.all([promise1, promise2(), promise3])/*...*/
Promise.all([promise1, promise2(), promise3
const 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将其转换为拒绝:


以上是当非承诺引发错误时,为什么Promise.all不会拒绝?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>