自定义Promise之all和race方法的实现

1. all方法的实现

all方法为Promise函数对象上的方法,参数为一个Promise实例所构成的数组,返回值为一个新的Promise实例。该实例的状态取决于传入的Promise实例数组,若该数组中所有的Promise实例都为fulfilled状态,则该实例就为fulfilled状态,结果为所有的Promise实例结果组合的数组;若该数组中有一个Promise实例为失败,则该实例就为rejected状态,结果为第一个失败的Promise实例的结果。

例如:

传入的所有实例都为成功时

let p1 = Promise.resolve(1)
let p2 = new Promise((resolve, reject) => {
    resolve(true)
})
let p3 = Promise.resolve('hello')

let res = Promise.all([p1, p2, p3])
console.log(res)  // [[PromiseState]]: "fulfilled" [[PromiseResult]]: [1, true, "hello"]

传入的实例至少有一个为失败时

let p1 = Promise.resolve(1)
let p2 = new Promise((resolve, reject) => {
    setTimeout(()=>{
        reject('error')
    }, 500)
})
let p3 = Promise.resolve('hello')

let res = Promise.all([p1, p2, p3])
console.log(res)  // [[PromiseState]]: "rejected" [[PromiseResult]]: "error"

实现:

  • 若传入的数组中有不为Promise的元素,则需先转换为Promise实例
  • 若所有传入的Promise实例都为成功,则返回的Promise结果数组的顺序需要与传入的顺序一致
/*
  返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接
  失败
  */
Promise.all = function (promises) {
    // 获取传入参数的长度
    const len = promises.length
    // 记录成功的实例个数
    let resolvedCount = 0
    // 存放结果
    const res = []
    // 返回新的Promise实例
    return new Promise((resolve, reject) => {
        // 遍历promises
        promises.forEach((item, index) => {
            // 若item不为Promise实例,需先将item转为Promise实例
            Promise.resolve(item).then(value => {
                // 将结果按顺序存入结果数组中
                res[index] = value
                // 有一个成功的Promise,则让计数器加一
                resolvedCount++
                // 判断是否全部成功
                if(resolvedCount === len) {
                    // 代表所有Promise实例都为成功状态
                    resolve(res)
                }
            }, reason => {
                // 如果有一个失败,则直接返回失败的Promise实例
                reject(reason)
            })
        })
    })
}

2. race方法的实现

all方法同样为Promise函数对象上的方法,参数也为一个Promise实例所构成的数组,返回值为一个新的Promise实例。该实例的状态取决于传入的Promise实例数组中第一个状完成态改变的Promise实例。

例如:

let p1 = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve(1)
    }, 500)
})

let p2 = new Promise((resolve, reject) => {
    setTimeout(()=>{
        reject(2)
    }, 0)
})

let p3 = Promise.resolve(3)

let res = Promise.race([p1, p2, p3])
console.log(res) // [[PromiseState]]: "fulfilled" [[PromiseResult]]: 3

由于p1, p2中执行器都是异步,而p3为同步得到状态,所以该Promise实例为p3的状态和结果。

实现:

/*
  返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
  */
Promise.race = function (promises) {
    // 返回新的Promise实例
    return new Promise((resolve, reject) => {
        // 遍历promises
        promises.forEach(item => {
            Promise.resolve(item).then(resolve, reject)
        })
    })
}

同样需要注意,如果传入的数组中有不为Promise实例,需要先使用Promise.resolve()转换为Promise实例

暂无评论

发送评论 编辑评论


				
上一篇
下一篇