手写Promise.all/race/any/settled方法

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)
                })
        })
    })
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值