Promise.all
Promise.all 的返回值是一个新的 Promise 实例。
Promise.all 接受一个可遍历的数据容器,容器中每个元素都应是 Promise 实例。咱就是说,假设这个容器就是数组。
数组中每个 Promise 实例都成功时(由pendding状态转化为fulfilled状态),Promise.all 才成功。这些 Promise 实例所有的 resolve 结果回按原来的顺序集合在一个数组中作为 Promise.all 的 resolve 的结果。
数组中只要有一个 Promise 实例失败(由pendding状态转化为rejected状态),Promise.all 就失败。Promise.all 的 .catch() 会捕获到这个 reject。
let p1 = new Promise((res, rej) => {
res('p-1')
})
let p2 = new Promise((res, rej) => {
setTimeout(() => {
res('p-2')
}, 1000)
})
Promise.all([p1, p2])
.then((res => {
console.log(res)
}))
.catch(err => {
console.log(err)
})
// ['p-1', 'p-2']
1、 如此,需要返回一个Promise对象
Promise.myAll = function (promises) {
return new Promise((resolve, reject) => {
})
}
2、返回的是一个数组,并且顺序可能出现混乱,所以还需要一个计数器
Promise.myAll = function (promises) {
let arr = []
let count = 0
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item)
.then(res => {
arr[i] = res
count++ // 当count的和传入数组长度相同的时候说明全部为成功
if (count == promises.length) resolve(arr)
})
.catch(reject)
});
})
}
验证一下
Promise.myAll([p1, p2])
.then(res => {
console.log('meRes:', res)
})
.catch(err => {
console.log('myErr:', err)
})
没啥问题
看看错误的情况,加一个返回失败的p3
let p3 = new Promise((res, rej) => {
rej('p-3')
})
Promise.myAll([p1, p2, p3])
.then(res => {
console.log('meRes:', res)
})
.catch(err => {
console.log('myErr:', err)
})
ok 了解了Promise.all的原理 同理得Promise.race
Promise.race
最快改变状态的Promise
Promise.myRace = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(item => {
Promise.resolve(item)
.then(res => {
resolve(res)
})
.catch(reject)
})
})
}
Promise.any
有一个成功即为成功 全部失败则为失败
// 正好和promise.all相反
Promise.myAny = function (promises) {
let arr = []
let count = 0
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item)
.then(res => {
resolve(res)
})
.catch(err => {
arr[i] = err
count++
if (count == promises.length) reject(new Error('All promises were rejected'))
})
})
})
}
Promise.allSettled
所有结果无论成功与否都会收集起来
先看下Promise.allSettled的运行结果
let p1 = new Promise((res, rej) => {
res('p-1')
})
let p2 = new Promise((res, rej) => {
setTimeout(() => {
res('p-2')
}, 1000)
})
let p3 = new Promise((res, rej) => {
rej('p-3')
})
Promise.allSettled([p1, p2, p3])
.then(res=>{
console.log(res)
})
返回的是一个数组,status标记状态,成功和失败分别将结果放在value和reason中
因为要将所有状态返回,所以无论成功还是失败的都需要将计数器加一
Promise.myAllSettled = function (promises) {
let arr = []
let count = 0
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item)
.then(res => {
arr[i] = { status: 'fulfilled', value: res }
count++
if (count == promises.length) resolve(arr)
})
.catch(err => {
arr[i] = { status: 'rejected', reason: err }
count++
if (count == promises.length) resolve(arr)
})
})
})
}