// 结果resolved的promise实例
const success = (ms, msg )=> new Promise(res => setTimeout(() => res(msg), ms));
// 结果rejected的promise实例
const fail = (ms, msg) => new Promise((res, rej)=>setTimeout(() => rej(msg), ms));
Promise.all([success(2000, "success_1"), success(1000, "success_2")]).then(console.log)
// ["success_1", "success_2"]
Promise.all([
success(2000, "success_1"),
success(1000, "success_2"),
fail(3000, "fail_1"),
fail(4000, "fail_2"),
])
.then(console.info)
.catch(console.error)
// "fail_1" 仅输出了 "fail_1", fail(4000, "fail_2")函数未执行
all
接收的promise
实例全部resolved
之后结果被then
捕获,promise.all
的状态变成resolved
,一旦有一个实例A的状态转为rejected
,那promise.all
的状态变成rejected
,此时的catch
捕获A的reject
信息。
再看 Promise.allSettled
:
Promise.allSettled([
success(2000, "success_1"),
success(1000, "success_2")
])
.then(console.info)
.catch(console.error)
/*
[{status: "fulfilled", value: "success_1"},
{status: "fulfilled", value: "success_2"}]
*/
Promise.allSettled([
fail(3000, "fail_1"),
fail(4000, "fail_2"),
])
.then(console.info)
.catch(console.error)
/*
[{status: "rejected", reason: "fail_1"},
{status: "rejected", reason: "fail_2"}]
*/
Promise.allSettled([
success(2000, "success_1"),
success(1000, "success_2"),
fail(3000, "fail_1"),
fail(4000, "fail_2"),
])
.then(console.info)
.catch(console.error)
/*
[{status: "fulfilled", value: "success_1"},
{status: "fulfilled", value: "success_2"},
{status: "rejected", reason: "fail_1"},
{status: "rejected", reason: "fail_2"}]
*/
当allSettled
接收的所有Promise
实例的状态都转变成resolved
或者rejected
时,then
直接捕获了最终的结果,用数组包裹。所以上面的catch
语句都可以去掉。
相比较来说,Promise.all
适合promise
实例相互依赖场景,因为状态(resolved)的转变依赖所有的实例。
Promise.allSettled
适合需要知道所有实例状态的场景,特别是实例rejected
的状态。
下面来验证下在Promise.all
中,一个实例rejected
之后其他实例还会不会执行。
const fail1 = (ms, msg) => new Promise((res, rej)=>setTimeout(() => {
rej(msg);
console.log("run");
}, ms));
Promise.all([
fail1(1000, "fail_1"),
fail1(2000, "fail_2"),
fail1(2000, "fail_2"),
fail1(2000, "fail_2"),
])
.then(console.info)
.catch(console.error)
当然会执行,只是catch
只会捕获首次抛出的错误。