开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
关于 Promise.all()
如果熟悉 Promise 的话,想必多多少少有用过或者了解 Promise.all(),Promise.all() 用于并行执行异步操作,即在所有异步操作执行完后才执行回调。
比较常见的场景就是需要调用多个接口,没有顺序的要求,但要获取到所有接口返回的数据之后再进行下一步操作。
- 【参数】:Promise.all() 参数是一个 promise 数组,数组里是Promise实例。
- 【结果】:执行后的返回值是一个promise,因为可以进行 promise.all().then()
- 【特点】:
- 在执行时,所有的 promise 对象都成功,才会触发成功,有一个失败就会返回失败
- 如果参数中包含非
promise的值,这些值会被忽略(Promise完成时,返回数组中这些值依旧存在)
代码实现
思路:
- 定义一个返回 Promise 的函数,参数为数组类型
- 判断传参是否是数组,如果不是,则 reject()
- 创建一个数组,用于存储执行后返回的数据,再用一个变量来进行异步执行计数(为了保证最后全部执行完毕后再返回)
- 遍历传递过来的 Promise 数组,Promise.resolve() 将异步的执行结果传递给 .then(),并计数。
- 所有异步执行完毕之后,resolve()传递最终结果
function promiseAll(array) {
return new Promise((resolve,reject) => {
if(!(array instanceof Array)) {
reject(new Error("参数不是有效的数组类型"))
}
let resultArr = new Array(array.length);
let count = 0;
for(let i=0; i<array.length; i++) {
Promise.resolve(array[i]).then( res => {
count++;
resultArr[i] = res;
if(count === array.length) {
resolve(resultArr)
}
}).catch(err => reject(err))
}
})
}
接下来定义一个Promise数组的生成器,setTimeout设置不同的执行时间,来模拟接口的执行(输出数组会看到是一个由多个 pending 状态的 Promise 组成的数组)
将生成的 Promise 数组传入写好的 PromiseAll()函数中,通过.then()来统一获取返回值
const promiseGenerator = (num) => {
return new Array(num).fill(0).map((item, index) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(index)
}, Math.random() * 1000)
})
})
}
const proAllArr = promiseGenerator(5)
console.log('proAllArr:',proAllArr)
promiseAll(proAllArr).then(console.log) // [ 0, 1, 2, 3, 4 ]
运行结果
[ 0, 1, 2, 3, 4 ] 即为 count === array.length 时,传递给.then() 的统一返回值。