Promise的all、any、race、allSettled方法的区别,及手写实现

一、共同点

  1. 这些方法的参数都接收一个promiseiterable类型(Array,Map,Set都属于ES6iterable类型)的输入
  2. 这些方法都返回一个promise的示例

二、各方法之间的区别

2.1返回的promise状态改变时机不同

  • all
    当所有的输入promise实例的状态都改变为fulfilled状态,新的promise实例才是fulfilled状态,返回所有输入promise实例的resolve value数组;
    如果有一个promise实例的状态是rejected,则新的promise实例的状态就是rejected,返回第一个promise reject的reason

  • allSettled
    返回所有promise实例执行的数组,格式如下:

[
  {
    
    status: "fulfilled", value: 1},
  {
    
    status: "rejected", reason: "error"},
  {
    
    status: "rejected", reason: 2},
]
  • any
    返回promise数组中最先变成fulfilled实例的value,如果,所有输入的promise实例的状态都是rejected, 返回all promise were rejected
  • race
    返回最先执行结束的promisevalue或者reason,不论状态是rejected还是fulfilled

2.2 返回的promise实例的终值或者拒因不同

  • all方法返回的promise实例终值是一个数组,数组的成员是所有输入的promise实例的终值,并将会按照参数内的promise顺序排列,而不是promise的完成顺序;拒因是输入的promise实例钟第一个状态变为rejected的拒因
  • allSettled方法返回的promise实例终值也是一个数组,顺序同promise的输入顺序一致,,其中每个成员在输入 promise resolved 状态时为 {status:‘fulfilled’, value:同一个终值},rejected 状态时为 {status:‘rejected’, reason:同一个拒因}

2,3 参数为空迭代对象时,返回值不同

  • all 方法会同步的返回一个已完成状态的promise, 终值值一个空数组
  • allSettled 方法和all表现形式相同
  • any 方法会同步的返回一个失败状态的promise,拒因是一个AggregateError对象
  • race 方法返回一个pending状态的promise

测试:

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

  const p2 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
      reject('p2 error')
    }, 1000)
  })

  const p3 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
      reject('p2 error')
    }, 1500)
  })

  Promise.all([p1, p2, p3])
    .then(res => console.log('then', res))
    .catch(err => console.log('catch', err))//catch p2 error

  Promise.race([p1, p2, p3])
    .then(res => console.log('then', res))//then 1
    .catch(err => console.log('catch', err))

  Promise.allSettled([p1, p2, p3])
    .then(res => console.log('then', res))//数组,结果见下图
    .catch(err => console.log('catch', err))

  Promise.any([p1, p2, p3])
    .then(res => console.log('then', res))//then 1
    .catch(err => console.log('catch', err))

  Promise.all([])
    .then(res => console.log('then', res))//[]
    .catch(err => console.log('catch', err))
  Promise.any([])
    .then(res => console.log('then', res))
    .catch(err => console.log('catch', err))//AggregateError: All promises were rejected
  Promise.allSettled([])
    .then(res => console.log('then', res))//[]
    .catch(err => console.log('catch', err))
  Promise.race([])//pengding状态不输出结果
    .then(res => console.log('then', res))
    .catch(err => console.log('catch', err))

在这里插入图片描述

三、手写实现

3.1 promise.all

function _all (promises) {
    
    
  /*
  * count 计数器,与len比较,判断是否所有的promise都已经成功了
  * result 用于存放成功的结果
  */
  let count=0,len=promises.length, result=[];
  return new Promise((resolve, reject) => {
    
    
    // 依次判断传入的promise实例是否成功
    for(let p of promises) {
    
    
      Promise.resolve(p).then(res => {
    
    
        result[count] = res;
        count++;
        if(count === len) {
    
    
          //相等,说明所有的promise实例都成功了, 才可以resolve结果
          resolve(result);
        }
      }).catch(err => 
      //只要有一个失败了就reject出去
      reject(err));
    }
  })
}

测试:

  const p1 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    resolve(1)}, 1000)
  });
  const p2 = new Promise((resolve, reject) => {
    
    
     setTimeout(() => {
    
    resolve(2)}, 2000)
  })
  const p3= new Promise((resolve, reject) => {
    
    
      setTimeout(() => {
    
    resolve(3)}, 3000)
    })
 _all([p1, p2, p3]).then(res=>console.log(res)).catch(err=> console.log(err))//三秒后打印[1,2,3]

3.2 promise.allSettled

function _allSettled (promises) {
    
    
  let result=[],len=promises.length; count=0;
  return new Promise((resolve, reject) => {
    
    
    for(let p of promises) {
    
    
      Promise.resolve(p).then(res => {
    
    
        result[count] ={
    
    
          status:'fulfilled',
          result:res
        }
        count++;
        if(count === len) {
    
    
          resolve(result)
        }
      }).catch(err => {
    
    
        result[count] ={
    
    
          status:'rejected',
          result:err
        }
        count++;
        if(count === len) {
    
    
          reject(result);
        }
      })
    }
  })
}

测试:_allSettled([p1, p2, p3]).then(res => console.log(res)).catch(err => console.log(err));
在这里插入图片描述

3.3 promise.any

function _any (promises) {
    
    
  let result =[],len=promises.length, count=0;
  return new Promise((resolve, reject) => {
    
    
    for(let p of promises) {
    
    
      Promise.resolve(p).then(res => {
    
    
        resolve(res);
      }).catch(err => {
    
    
        result[count]=err;
        count++;
        if(count===len){
    
    
          reject(result)
        }
      })
    }
  })
} 

3.4 promise.race

function _race (promises) {
    
    
  return new Promise((resolve, reject) => {
    
    
    for(p of promises) {
    
    
      Promise.resolve(p).then(res => {
    
    
        resolve(res)
      }).catch(err=> reject(err))
    }
  })
} 

3.5 Promise.prototype.finally

Promise.prototype._finally = function (cb) {
    
    
// 谁调用finally,this就是谁
  return this.then(
  // 不管调用finally的promise是什么状态,都执行回调函数
    value => Promise.resolve(cb()),
    error => Promise.reject(cb())
  )
}

明白各个方法的作用,理清楚思路,代码实现真的很简单。

猜你喜欢

转载自blog.csdn.net/weixin_44761091/article/details/124006654
今日推荐