promise.all
入参: 是一个promise的iterable,就是参数是可以被for...of的迭代器,可以迭代的,有Array,Map, Set
出参:一个Promise实例,入参中有一个promise为rejected状态,则promise.all直接rejected第一个错误信息,但是,入参中的其他promise还是会各自执行到Fulfillment/Rejection的状态。
/**
* @desc 手写一个Promise.all
* @param Iterable list 一个promise的迭代器
* @return promise 一个promise实例
*/
function all(list) {
// 首先返回一个promise实例
return new Promise((resolve, reject) => {
// 判断入参是否为一个可迭代对象(目前,我也不知道怎么判断,就判断是否是一个数组)
if(!Array.isArray(list)) {
return reject("argument is not iterable")
}
// 定义的迭代器,来存放数据(这里以处理Array为栗子)
const arr = [];
// 定义一个计数器,来统计迭代对象中的有多少Promise处理完成
let count = 0;
// Array Set Map都有forEach方法遍历
list.forEach((v, i) => {
// 使用Promise.resolve的静态方法将入参中的每一项变成一个Promise
Promise.resolve(v)
.then(res => {
// 将入参中promise放回的结果放到对应的result对应的位置上
result[i] = res;
// 判断是否所有promise都完成,不能使用result.length === list.length
// 因为数据的length值,是根据数组最后一个数据的下标来决定的
if(++count === list.length) {
// 如果所有promise都处理完成,则返回result
resolve(result)
}
})
.catch(err => {
reject(err);
})
})
})
}
注意点:
const arr = [];
arr[3] = 111;
arr.length === 4 // true
JavaScript 数组length的返回值,是根据最后一个元素所在的下标决定的