携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
前言
Promise.all为Promise api中为数不多开发中常用的api。你能够独立实现它吗?如果还不够清晰可以和我一起通过这篇文章了解它。
阅读这篇文章,需要你掌握的知识👇
- Promise基本知识
其中Promise基础知识如果不了解或有遗忘的同学可以参考我这篇文章:《简单明了的Promise基本知识点》
规定
Promise.all:
Promise.all()方法接收一个 promise 的iterable类型(注:Array,Map,Set 都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。- 如果传入的参数是一个空的可迭代对象,则返回一个已完成(fulfilled)状态的 Promise
- 这个
Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。 - 它的 reject 回调执行是,只要任何一个输入的
promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
实现Promise.all
先创建一个函数名为myPromiseAll的函数,它接受一个promiseiterable 类型的参数👇
const myPromiseAll = function(promiseArray){
if(Array.isArray(promiseArray)){
}
}
那么参数类型不正确时应该干嘛呢?我们在参数类型不符合要求时,抛出一个错误👇
const myPromiseAll = function(promiseArray){
if(Array.isArray(promiseArray)){
}else{
throw new Error('argument type is not iterable')
}
}
接着,返回一个Promise实例:
const myPromiseAll = function(promiseArray){
if(Array.isArray(promiseArray)){
return new Promise((resolve,reject)=>{
let result = []//输入的所有 `promise` 的 `resolve` 回调的结果是一个数组。
})
}else{
throw new Error('argument type is not iterable')
}
}
- 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
const myPromiseAll = function(promiseArray){
if(Array.isArray(promiseArray)){
return new Promise((resolve,reject)=>{
if (promiseArray.length == 0){
return Promise.resolve(promiseArray)
}
let result = []
})
}else{
throw new Error('argument type is not iterable')
}
}
- 这个
Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。 - 它的 reject 回调执行是,只要任何一个输入的
promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
const myPromiseAll = function(promiseArray){
if(Array.isArray(promiseArray)){
return new Promise((resolve,reject)=>{
if (promiseArray.length == 0){
return Promise.resolve(promiseArray)
}
let result = []
let count = 0
promiseArray.forEach((item,index)=>{
Promise.resolve(item).then(value => {
count++//这里计数是为了判断所有的promise都是正确执行的
result[index] = value
count == promiseArray.length && resolve(result)//当所有的项都正确执行了,才会使这个promise执行
},
value => {
reject(value)//当出现错误时,就不累加count了,并抛出错误
} )
})
})
}else{
throw new Error('argument type is not iterable')
}
}
大功告成🤩
测试
用一段测试代码来测试我们的myPromiseAll👇
const p1 = Promise.resolve(3);
const p2 = {
then: function (onFulfill) {
onFulfill('then函数')
}
}
const p3 = 42;
myPromiseAll([p1, p2, p3]).then(result => {
console.log('原生 all fulfilled :>> ', result);
}, reason => {
console.log('原生 all rejected :>> ', reason)
})
输出
原生 all fulfilled :>> [ 3, 'then函数', 42 ]
测试通过!
尾声
Promise.all的实现比较简单,不熟悉的同学多加练习就一定能掌握啦💪