js 手动实现 promise.all的功能

  • Post author:
  • Post category:小程序
在中高级面试中,实现一个promise.all是一个频率较高的面试题
首先分析下 promise.all(),(参考MDN)
  1. 接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的参数
  2. 返回一个promsie实例
  3. 参数里所有的promise都成功回调后 resolve返回一个数组结果,数组顺序和参数顺序一致
  4. 参数里有一个失败的就会reject,并且reject第一个失败的信息
// 下面实现一下
  Promise.prototype.all = function (iterators) {
    const promises = Array.from(iterators); // 强制转换成数组
    const len = promises.length; // 记录数组的长度
    let count = 0; // 标记成功的个数
    let resultList = [];// 要返回的 数组结果
    return new Promise((resolve, reject) => {  // 返回一个promise 
      for (let index in promises) { // for 循环配合 let 确保 数组结果和参数顺序一致
        Promise.resolve(promises[index])         // Promise.resolve,如果是参数是promise 直接返回,如果不是则直接执行Promise.resolve方法 到 then 接受 
          .then((result) => {
            count++;          // 记录个数,等于len时 resolve
            resultList[index] = result; // 对应赋值结果
            if (count === len) {
              resolve(resultList);
            }
          })
          .catch(e => { 
            reject(e); // 当收到错误时,直接reject,返回错误信息
          })
      }
    })
  }


 let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('1')
    }, 5000);
  })
  let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('2')
    }, 2000);
  })
  let p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('3')
    }, 3000);
  })
  let p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('4')
    }, 4000);
  })
  Promise.all([p1, p2, p3, p4]).then(res => {
    console.log(res,'res') 
  }).catch(err => {
    console.log(err)
  })
//  ['1', '2', '3', '4'] 'res' 
理解其中的逻辑,其实并不复杂