相同点
- 都可以接受一组promise实例作为参数,并包装成一个新的promise实例
不同点
首先明确一点promise状态的变化:
pending -> resolve方法 -> fulfilled -> resolved
pending -> reject方法 -> rejected -> resolved
相同参数对应的处理方式的不同
Promise.allSettled()
Promise.allSettled()不管参数中的promise是fulfilled还是rejected,都会等参数中的实例都返回结果,包装实例才会结束。
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();
Promise.all()
Promise.all()只有在接受的所有promise实例全部是fulfilled才会走Promise.all([p1,p2,p3]).then()方法,只要有其中一个promise实例是rejected,就会直接走catch方法,并且catch中只会返回第一个变成rejected的promise的错误
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
throw new Error('p2报错');
})
.then(result => result);
const p3 = new Promise((resolve, reject) => {
throw new Error('p3报错')
})
.then(result => result);
Promise.all([p1, p2, p3])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: p2报错
当然,这里需要注意,上面的代码中,如果p2本身有自己处理自己promise实例的catch方法,则会自己捕捉自己的错误,不会走all.catch
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
throw new Error('p2报错');
})
.then(result => result)
.catch(e=>console.log(e)) // Error: p2报错
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", undefined]
对于包装实例本身
Promise.allSettled()
一旦有了结果,包装实例本身总是fulfilled状态
Promise.all()
必须是接受参数中的所有promise实例都变为fulfilled状态,包装实例本身才会变为fullfilled状态,否则有一个接受参数中有一个rejected,则包装实例就是rejected状态
返回的数据结构
Promise.allSettled()
接受的结果与入参时的promise实例一一对应,且结果的每一项都是一个对象,告诉你结果和值,对象内都有一个属性叫“status”,用来明确知道对应的这个promise实例的状态(fulfilled或rejected),fulfilled时,对象有value属性,rejected时有reason属性,对应两种状态的返回值。
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
重要的一点是,他不论接受入参的promise本身的状态,会返回所有promise的结果,但这一点Promise.all做不到,如果你需要知道所有入参的异步操作的所有结果,或者需要知道这些异步操作是否全部结束,应该使用promise.allSettled()
Promise.all()
只有当所有入参的promise实例都是fulfilled状态,才会在Promise.all().then()方法中结果,返回结果也是与入参一一对应,结果中只包含实际的resolve的结果,不包含类似allSettled的status和value属性。
如上学习总结,部分来自阮一峰老师的ES6,还有自己的思考
如有不对的地方,欢迎指正~