1.Promise.all
先看Promise.all MDN的定义:
Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。
也就是说Promise.all 只要一个失败的话,就会失败,返回的第一个失败结果。
Promise.all 正常执行的结果
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
Promise.all的快速返回失败行为
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
reject('reject');
});
Promise.all([p1, p2, p3, p4, p5]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});
//From console:
//"reject"
//You can also use .catch
Promise.all([p1, p2, p3, p4, p5]).then(values => {
console.log(values);
}).catch(reason => {
console.log(reason)
});
//From console:
//"reject"2.Promise.allSettled
而Promise.allSettled MDN的定义:
Promise.allsettled(iterable) 方法方法返回一个在所有给定的promise已被决议或被拒绝后决议的promise,并带有一个对象数组,每个对象表示对应的promise结果
Promise.allSettled不会向Promise.all那样,只要一个失败就返回第一个失败结果,而是所有的结果(不管是失败还是成功的),都会返回,其结果都是一个数组。
例子:
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result.status)));
// expected output:
// "fulfilled"
// "rejected"
不过需要引起注意的是Promise.allSettled 在TC39第四草案阶段,还得注意兼容性,比如Chrome要76以上版本才支持。兼容性问题可以通知引入其垫片promise.allsettled来解决。
3.结论
通过以上对比,我们可以发现要想每个promise都执行的话,要用Promise.allSettled,而要快速返回失败结果的话可以使用Promise.all。如果每个结果都正常执行的话,Promise.all和Promise.allsettled返回的结果是一样的。