Es6实现Promise.all和Promise.race

本文深入探讨了Promise.all和Promise.race方法的实现原理,包括如何处理非Promise对象,确保值按顺序输出,以及一旦出现reject即刻改变状态的特性。通过自定义函数myPromiseAll和myPromiseRace,展示了如何在实际应用中控制并发请求,限制最大并发数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Promise.all([p1,p2,p3])中,all方法的参数条件

  • 必须为数组
  • 可以传入非promise,all自动将其转换为promise对象
  • 传入的值必须按顺序输出
  • 一旦又一个reject则状态立马变为reject,并将错误原因抛出
function myPromiseAll(promiseArr){
    // 为了让传入的值不是promise也返回promise
    return new Promise((resolve,reject) => {
        if(!Array.isArray(promiseArr)){
            throw('promiseArr必须为数组')
        }
        let resArr = []
        let len = promiseArr.length;
        let count = 0;
        for(let i = 0; i < len; i++){
            // Promise.resolve将数组中非promise转为promise
            Promise.resolve(promiseArr[i])
            .then(value => {
                count++
                resArr[i] = value
                
                if(count == len) return resolve(resArr)
            })
            .catch(err => {
                return reject(err)
            })
           
        }
    })
    
}

let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = Promise.resolve(3)

myPromiseAll([p1,p3,p2]).then(res => {
    console.log(res); // [1,3,2]
    
})

Promise.race()实现

function myPromiseRace(promiseArr){
    return new Promise((resolve,reject) => {
        if(!Array.isArray(promiseArr)) throw('参数必须为数组')
        let len = promiseArr.length
        for(let i = 0; i < len; i++){
            Promise.resolve(promiseArr[i]).then(val => {
                resolve(val)
            }).catch(err => {
                reject(err)
            })
        }
        
    })
   

}

测试


let p1 = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject(1)
    },50)
})
let p2 = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject(22)
    },100)
})
let p3 = new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve(3)
    },700)
})
myPromiseRace([p2,p3,p1])
.then(res => console.log(res)) 
.catch(err=>console.log(err)) // 1

Promise实战,QPS为3,但是同时发出5个请求

  • 实现一个直接的PromiseAll
function myPromiseAll(promiseArr){
    // 为了让传入的值不是promise也返回promise
    return new Promise((resolve,reject) => {
        if(!Array.isArray(promiseArr)){
            throw('promiseArr必须为数组')
        }
        let resArr = []
        let len = promiseArr.length;
        let count = 0;
        for(let i = 0; i < len; i++){
            // Promise.resolve将数组中非promise转为promise
            Promise.resolve(promiseArr[i])
            .then(value => {
                count++
                resArr[i] = value
                
                if(count == 3) return resolve(resArr)  //这里设置了并发最大为3,就返回结果
            })
            .catch(err => {
                return reject(err)
            })
           
        }
    })
    
}

let wake = (time) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(`${time / 1000}秒后醒来`)
      }, time)
    })
  }
  
  let p1 = wake(2000)
  let p2 = wake(3000)
  let p3 = wake(4000)
  let p4 = wake(5000)
  let p5 = wake(6000)
  
 let start = new Date().getSeconds()
  myPromiseAll([p1,p2,p3,p4,p5]).then(res => {
    console.log(res); // [ '2秒后醒来', '3秒后醒来', '4秒后醒来' ]
    console.log(`耗时:${new Date().getSeconds() -start }`); //4
    
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值