实现 Promise.all 和 Promise.race

手写 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 状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值