Promise.all()
原理简述:
MDN:
- Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入。
- 并且只返回一个Promise实例, 输入的所有promise的resolve回调的结果是一个数组。
- Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。
- 它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
简单实现:
为了测试结果更直观一些,这里使用真实接口(来自我的博客:kayrain.cn)
function fetchAction(url) {
return new Promise((resolve, rejected) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(JSON.parse(xhr.responseText))
} else {
rejected('网络错误')
}
}
xhr.open('get', url);
xhr.send(null);
})
}
const p1 = fetchAction("https://www.kayrain.cn/api/post/list?pageNo=1&pageSize=10&title=&tag=")
const p2 = fetchAction("https://www.kayrain.cn/api/post/list?pageNo=1&pageSize=10&title=&tag=")
// 将p3定义为错误请求
const p3 = fetchAction("https://www.kayrain.cn/api/post/list")
实现all():
Promise.newAll = function(promises) {
return new Promise((resolve, reject) => {
let list = [],
len = promises.length,
count = len;
for (let i = 0; i < len; i++) {
promises[i].then(res => {
list[i] = res;
if (--count === 0) {
resolve(list)
}
}, error => {
reject(error)
})
}
})
}
Promise.newAll([p1, p2, p3]).then(res => console.log('Promise.all:', res))
运行代码,由于有错误请求出现,所以打印结果为:
将p3改为正确请求,全部resolve后的结果为:
Promise.allSettled()
原理简述:
MDN:
- Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
- 当有多个彼此不依赖的异步任务成功完成时,或者总是想知道每个promise的结果时,通常使用它。
相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。- 简言之Promise.allSettled 只关心所有 promise 是不是都被 settle 了,不管其是 rejected状态的 promise,还是非 rejected状态(即fulfilled)的 promise, 都可以拿到它的最终状态并对其进行处理。
简单实现
Promise.newAllSettled = function(promises) {
return new Promise(resolve => {
let list = [],
len = promises.length,
count = len;
for (let i = 0; i < len; i++) {
promises[i].then(res => {
list[i] = {
status: 'fulfilled',
value: res
};
}, error => {
list[i] = {
status: 'rejected',
reason: error
};
}).finally(() => {
// 循环完成后再resolve,防止出现空属性
if (--count === 0) resolve(list);
})
}
})
}
Promise.newAllSettled([p1, p2, p3]).then(res => console.log('Promise.allSettled:', res))
运行代码,打印结果为: