手写 Promise.all

152 阅读1分钟

Promise.all 功能描述

  • Promise.all 返回值是一个 Promise 实例
  • Promise.all 接受一个可遍历的数据容器,容器中每个元素都应是 Promise 实例
  • 数组中每个 Promise 实例都成功时(由 pendding 状态转化为 fullfilled 状态),Promise.all 才成功。这些 Promise 实例所有的 resolve 结果会按照原来的顺序集合返回在一个数组中作为 Promise.all 的返回结果。
  • 数组中只要有一个 Promise 实例失败(状态由 pendding 状态转化为 rejected 状态),Promise.all 就算失败。Promise.all.catch() 会捕获到这个 reject

Promise.all 手写代码实现

function myPromiseAll(promises){
  // 用于判断是否所有promise都成功
  let count = 0;
  // 返回结果
  const result = [];
  return new Promise(function(resolve, reject){
    promises.forEach((promise, i)=>{
      Promise.resolve(promise).then(res=>{
        // 按顺序存储返回结果
        result[i] = res;
        // 所有promise都成功,返回请求结果
        if(++count === promises.length){
          resolve(result);
        }
      }, reject); // 处理失败
    });
  });
}

测试

const p1 = Promise.resolve('p1');
const p2 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve('p2 延时一秒')
  }, 1000);
});

const p3 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve('p3 延时两秒')
  }, 2000);
});

myPromiseAll([p1,p2,p3]).then(res=>console.log(res)).catch(err=>console.log(err));
// 两秒后打印  ['p1', 'p2 延时一秒', 'p3 延时两秒']
const p1 = Promise.resolve('p1');
const p2 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve('p2 延时一秒')
  }, 1000);
});

const p3 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve('p3 延时两秒')
  }, 1000);
});

const p4 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    reject('p4 rejected 延时三秒')
  }, 3000);
});

myPromiseAll([p1,p2,p3,p4]).then(res=>console.log(res)).catch(err=>console.log(err));
// 三秒后打印  p4 rejected 延时三秒