实现Promise.all方法
功能:Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
function test(i) {
return new Promise((resolve, reject) => {
if (Math.random() < 0.9) {
resolve(i)
} else {
reject(i)
}
})
}
//存储Promise的数组
const arr = [];
for (let i = 0; i < 10; i++) {
//向数组内添加多个Promise对象
arr.push(test(i))
}
const p = Promise.all(arr)
p.then(result => {
//如果全部为resolved状态则为一个成功的数组
//例如:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(result)
}, err => {
//如果其中有个的状态为rejected状态则直接推出失败的状态的结果
//例如:第一个失败了则输出2
console.log(err)
})
按照其实现的功能,模拟代码如下
function PromiseAll(pros) {
//返回一个新的Promise对象
return new Promise((resolve, reject) => {
//判断传入的是否是一个可迭代对象
if (!pros[Symbol.iterator]) {
throw TypeError(typeof pros +' is not iterable (cannot read property Symbol(Symbol.iterator))')
}
//声明一个数组存放所有成功的结果
const arr = []
//判断传入的数据是否为一个字符串,如果是则用''分割成数组
pros = typeof pros == 'string' ? pros.split('') : pros
//遍历数组中的每一项
pros.forEach((pro, index) => {
Promise.resolve(pro).then(data => {
//当状态为成功时结果添加进成功数组中
arr.push(data)
//当成功数组的长度与Promise对象数组的长度一致时,表示前面的Promise结果也为成功,
//则推出成功状态,与成功结果的数组
if (arr.length == pros.length) {
resolve(arr)
}
}, err => {
//如果有一个失败的直接推出失败状态与失败的状态的结果
reject(err)
})
});
})
}