手写 Promise.all
Promise.all ,接收参数为一个数组promises,返回一个 promise实例,假设叫做 promiseAllResult
promises中不为promise实例的元素会被转化为promise实例,promises中所有元素的状态都转为fulfilled时,promiseAllResult的状态转变为fulfilled,promiseAllResult的值为一个数组,包含所有promises的值
实现代码:
function myPromiseAll (promises) {
// 返回一个promise实例
return new Promise((resolve, reject) => {
let len = promises.length
// 记录当前已经 fulfilled 的 promise 的个数
let resolvedCount = 0
let promiseValues = []
for (let i = 0; i < len; i++) {
// 非 promise 的元素可以转为 fulfilled 状态的 promise
let promise = Promise.resolve(promises[i])
promise
.then((val) => {
resolvedCount ++
// 结果数组中添加值,注意不要直接push,因为.then 是异步操作
// Promise.all 的结果数组中顺序和参数数组中的顺序是一样的
promiseValues[i] = val
// 如果所有的promise都fulfilled了,就resolve,转变这个promiseAllResult 为 fulfilled 状态
if (resolvedCount === len) {
resolve(promiseValues)
}
}, (err) => {
// 如果有一个promise是rejected状态,就reject,,转变这个promiseAllResult 为 rejected 状态
reject(err)
})
}
})
}
手写 Promise.race
Promise.all 传入一个数组promises,
返回一个promise实例,
如果传入的promises中有一个状态不为pending,则返回的promiseAllResult的状态和值都为那个率先发生状态改变的promise
实现代码:
function myPromiseRace (promises) {
return new Promise ((resolve, reject) => {
let len = promises.length
for (let i = 0; i < len; i++) {
// 非 promise 的元素可以转为 fulfilled 状态的 promise
let promise = Promise.resolve(promises[i])
// 注意,下面一定要用.then两个参数,不能用.then和.catch,
// 因为.then 和 .catch 都是异步操作,会有延迟,如果一个rejected的promise率先触发,它虽然说只是会触发.catch,但是会经过.then,导致触发.catch的时机延后,可能后面的就先触发.then了
promise
.then(val => {
resolve(val)
}, err => {
reject(err)
})
}
})
}
测试一下
写个小case测试一下
let p1 = new Promise ((resolve, reject) => {
setTimeout(() => {
resolve('p1')
}, 500)
})
let p2 = Promise.resolve('p2')
let p3 = Promise.reject('p3')
myPromiseAll([p1, p2, 'hhh'])
.then((result) => {
console.log('then', result) // then [ 'p1', 'p2', 'hhh' ]
})
.catch((error) => {
console.log('catch', error)
})
myPromiseRace([p3, p1, p2])
.then((result) => {
console.log('then', result)
})
.catch((error) => {
console.log('catch', error) // catch p3
})
会先输出 catch p3
,再输出then [ 'p1', 'p2', 'hhh' ]
,因为 Promise.all 会 等所有传入的 promise 都转为 fulfilled,它返回的 promise 才会转为 fulfilled 状态