JS 中 Promise.all() 和 Promise.allSettled() 的区别?
Differences between Promise.all() and Promise.allSettled() in JS?
我正在阅读 MDN 关于 Promise 的手册,我发现这两种方法与我相似:
它们都采用 iterable 和 return 包含已实现的 Promise
s 的数组。
那么,它们有什么区别呢?
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
我正在阅读 MDN 关于 Promise 的手册,我发现这两种方法与我相似:
它们都采用 iterable 和 return 包含已实现的 Promise
s 的数组。
那么,它们有什么区别呢?
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