JS 中 Promise.all() 和 Promise.allSettled() 的区别?

Differences between Promise.all() and Promise.allSettled() in JS?

我正在阅读 MDN 关于 Promise 的手册,我发现这两种方法与我相似:

它们都采用 iterable 和 return 包含已实现的 Promises 的数组。

那么,它们有什么区别呢?

Promise.all 将在数组中的 一个 Promise 拒绝后立即拒绝。

Promise.allSettled 永远不会拒绝 - 它会解决一次 all 数组中的承诺要么被拒绝要么被解决。

他们的解析值也不一样。 Promise.all 将解析为 Promise 解析为的每个值的数组 - 例如 [Promise.resolve(1), Promise.resolve(2)] 将变成 [1, 2]Promise.allSettled 会给你 [{ status : 'fulfilled', value: 1 }, { status : 'fulfilled', value: 2 }].

Promise.all([Promise.resolve(1), Promise.resolve(2)])
  .then(console.log);
Promise.allSettled([Promise.resolve(1), Promise.resolve(2)])
  .then(console.log);

如果其中一个 Promise 拒绝,Promise.all 将以拒绝的值拒绝,但 Promise.allSettled 将在数组中的那个位置以 { status: 'rejected', reason: <error> } 的对象解决.

Promise.all([Promise.reject(1), Promise.resolve(2)])
  .catch((err) => {
    console.log('err', err);
  });
Promise.allSettled([Promise.reject(1), Promise.resolve(2)])
  .then(console.log);

当你想确保你正在使用的操作的承诺都应该是 resolved/success 时,你需要使用 Promise.all 因为它在每个承诺得到解决时完成.

但是如果你只想完成所有的承诺,不管它们是被解决还是被拒绝,那么使用 Promise.allSettled.

它们都批量执行 promise,但细微差别在于它们处理 promise 迭代的方式。

Promise.all: 它仅在 all 传递给它的承诺(作为数组)解析时解析,否则它将拒绝第一个 被拒绝的承诺错误。

Promise.all已解决:这个问题将总是通过包含已解决信息的数组解决并且 拒绝了承诺。 仔细查看结果数组的以下属性(状态、值、原因)。

-------------------------------------------- ---------- 示例 1 ---------------------------------- ----------------------

const pms1 = Promise.resolve(1);
// setTimeout(function, milliseconds, param1, param2, ...)
const pms2 = new Promise((resolve, reject) => { setTimeout(resolve, 200, 2); });
const pms3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 3); });
const pmsAry = [pms1, pms2, pms3];

Promise.all(pmsAry)
.then(resAry => console.log(resAry)) // resAry order is same as pmsAry order
.catch(error => console.log(error));

/* 
 * Note here we are not writing 'catch' because Promise.allSettled ALWAYS RESOLVES
 * with array containing information about resolved or rejected promises
 */
Promise.allSettled(pmsAry)
.then(resAry => console.log(resAry)); // resAry order is same as pmsAry order

输出:

[1, 2, 3] 
// Promise.all output ORDER doesn't depend on promise resolution time

[{ status: "fulfilled", value: 1 },
 { status: "fulfilled", value: 2 }, 
 { status: "fulfilled", value: 3 }]
// Promise.allSettled output ORDER doesn't depend on promise resolution time

-------------------------------------------- ---------- 例2 ---------------------------------- ----------------------

const pms1 = Promise.resolve(1);
const pms2 = new Promise(
                 (resolve, reject) => { setTimeout(reject, 200, '200ms Err'); }
             );
const pms3 = new Promise(
                 (resolve, reject) => { setTimeout(reject, 100, '100ms Err'); }
             );
const pmsAry = [pms1, pms2, pms3];

Promise.all(pmsAry)
.then(resAry => console.log(resAry))
.catch(error => console.log(error));

Promise.allSettled(pmsAry)
.then(resAry => console.log(resAry));

输出:

100ms Err
/* 
 * Note: Here there are TWO promises which are getting REJECTED but output is
 * ONLY ONE (i.e the one which is getting rejected FIRST) 
 */

[{ status: "fulfilled", value: 1 },             // Note: value
 { status: "rejected", reason: "200ms Err" },   
 { status: "rejected", reason: "100ms Err" }]   // Note: reason