Promise.all()描述
- Promise.all的
返回值是一个新的Promise实例 - Promise.all接受一个可遍历的数据容器,
容器中每个元素都应是Promise实例。容器可以定义为数组。 数组中每个Promise实例都成功时(由pendding状态转化为fulfilled状态),Promise.all才成功。这些Promise实例所有的resolve结果会按原来的顺序集合在一个数组中作为Promise.all的resolve的结果数组中只要有一个Promise实例失败(由pendding状态转化为rejected状态),Promise.all就失败。此时第一个被reject的实例的返回值,会传递给p的回调函数。
思路
- Promise.all接受一个数组,返回值是一个新的Promise实例
Promise.MyAll = function(promise){
return new Promise((resolve,reject)=>{})
}
- 数组中所有Promise实例都成功,Promise.all才成功。需要一个数组收集这些Promise实例的resolve结果。万一数组里面有元素不是Promise,就需要用Promise.resolve()解决。Promise实例是不能直接调用resolve方法的,用.then()去收集结果
Promise.MyAll = function(promise){
let arr = []
return new Promise((resolve,reject)=>{
promise.forEach((item,i)=>{
Promise.resolve(item).then(res=>{
arr[i] = res
})
})
})
}
- 将收集到的结果(数组arr)作为参数传给外层的resolve方法。
Promise.MyAll = function(promise){
let arr = []
count = 0
return new Promise((resolve,reject)=>{
promise.forEach((item,i)=>{
Promise.resolve(item).then(res=>{
arr[i] = res
count += 1
if(count === promise.length)resolve(arr)
})
})
})
}
- 最后处理失败的情况,用.catch()方法捕获失败
Promise.MyAll = function(promise){
let arr = []
count = 0
return new Promise((resolve,reject)=>{
promise.forEach((item,i)=>{
Promise.resolve(item).then(res=>{
arr[i] = res
count += 1
if(count === promise.length)resolve(arr)
}).catch(reject)
})
})
}
总结
Promise.myAll = (promises) => {
return new Promise((rs, rj) => {
// 计数器
let count = 0
// 存放结果
let result = []
const len = promises.length
if (len === 0) {
return rs([])
}
promises.forEach((p, i) => {
// 注意有的数组项有可能不是Promise,需要手动转化一下
Promise.resolve(p).then((res) => {
count += 1
// 收集每个Promise的返回值
result[ i ] = res
// 当所有的Promise都成功了,那么将返回的Promise结果设置为result
if (count === len) { rs(result) }
// 监听数组项中的Promise catch只要有一个失败,那么我们自己返回的Promise也会失败
})
.catch(rj)
})
})
}
// 测试一下
const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => { setTimeout(() => resolve(2), 1000) })
const p3 = new Promise((resolve) => { setTimeout(() => resolve(3), 3000) })
const p4 = Promise.reject('err4')
const p5 = Promise.reject('err5')
// 1. 所有的Promise都成功了
const p11 = Promise.myAll([ p1, p2, p3 ])
.then(console.log) // [ 1, 2, 3 ]
.catch(console.log)
// 2. 有一个Promise失败了
const p12 = Promise.myAll([ p1, p2, p4 ])
.then(console.log)
.catch(console.log) // err4
// 3. 有两个Promise失败了,可以看到最终输出的是err4,第一个失败的返回值
const p13 = Promise.myAll([ p1, p4, p5 ])
.then(console.log)
.catch(console.log) // err4 // 与原生的Promise.all返回是一致的
额外题目
使用Promise.all进行5个请求,若其中一个失败,如何返回其他4个成功???
Promise.MyAll = function(promise){
let arr = []
count = 0
return new Promise((resolve,reject)=>{
promise.forEach((item,i)=>{
Promise.resolve(item).then(res=>{
arr[i] = res
}).catch((err)=>{
arr[i]= false
}).finally(()=>{
count ++ ;
if(count === promise.length)resolve(arr)
})
})
})
}
Promise.race()
Promise.MyRace = function(promise){
return new Promise((resolve,reject)=>{
for(const item of promise){
Promise.resolve(item).then(resolve,reject)
}
})
}