Promise.all() 返回一个新的 Promise 对象,该对象在所有传入的 Promise 对象都已解决时才会被解决,并且该对象的解决值是一个数组,包含所有传入 Promise 对象的解决值,这些值的顺序与传入的 Promise 对象的顺序相同。
有以下几个注意点
- 写在 Promise 上,而不是原型上
- 入参是Promise对象组成的可迭代对象(通常是数组),返回 promise 对象
- 使用数组记录结果,注意不能直接 push
- 计数器与数组长度一致时,说明都 resolve
- 只要有一个 reject 就整体 reject
- 如果传入
Promise.all()的可迭代对象为空,则返回的 Promise 对象会立即解决,并且解决值为一个空数组([]) - 需要将 list 非 promise 项转化
Promise.myAll = (list) => {
let results = [] // 存放结果
let count = 0 // 计数器
return new Promise((resolve, reject) => {
if (list.length === 0) {
resolve([])
}
list.map((promise, index) => {
Promise.resolve(promise).then((res) => {
// 结果与传入的 promise 顺序保持一致,不能直接 push
results[index] = res
count++
if (count >= list.length) {
resolve(results)
}
}, (err) => {
reject(err)
})
})
})
}
以下是测试代码
const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => {
setTimeout(() => resolve(2), 1000)
})
const p3 = new Promise((resolve) => {
setTimeout(() => resolve(3), 3000)
})
const notPromise = 'notPromise'
const p4 = Promise.reject('err4')
const p5 = Promise.reject('err5')
// 1. 所有的Promise都成功了
const p11 = Promise.myAll([p1, p3, p2, notPromise])
.then(console.log) // [1, 3, 2, 'notPromise']
.catch(console.log)
// 2. 有一个Promise失败了
const p12 = Promise.myAll([p1, p2, p4])
.then((res) => console.log(res))
.catch((err) => console.log(err)) // err4
// 3. 有两个Promise失败了,可以看到最终输出的是err4,第一个失败的返回值
const p13 = Promise.myAll([p1, p4, p5]).then(console.log).catch(console.log) // err4
// 4. 传入空数组
const p14 = Promise.myAll([]).then(console.log).catch(console.log) // []