JS手写Promise.all方法

124 阅读1分钟

难点分析:

1. 如何保证成功结果与传入的数组一一对应

  1. new一个数组用于存放结果
  2. 循环传入的数组,将成功结果存放与结果数组的对应索引里

2. 如果传入的数组中,有不是promise实例

  1. 循环时,将每一个元素用Promise.resolve包裹

3. 每个promis返回结果的时间都不一定,如何判断数组中的每一个实例都拿到了结果

  1. 定义一个count记录(初始值为0),在then方法中,每次成功都加一
  2. 当count等于传入的数组长度时,则说明所有的实例都已经拿到了成功的结果,此时再返回所有结果

实现代码:

// 封装promise.all2方法
Promise.all2 = function(arr){
  // 返回一个promise
  return new Promise((resolve,reject)=>{
    let len = arr.length
    let count = 0   // 用于记录循环是否完成
    let result = new Array(len)   // 记录成功结果
    arr.forEach((p,index) => {
      // 使用Promise.resolve包裹,解决传入的参数不是promise实例的报错
      Promise.resolve(p).then((res)=>{
        result[index] = res
        count++
        if (count===len){  // 所有元素都已经拿到了结果
          resolve(result)
        }
      },err=>{
        reject(err)
      })
    });
  })
}

// 测试代码
let p1 = new Promise((resolve,reject)=>{
  setTimeout(()=>{
    resolve("p1成功")
  },3000)
})
let p2 = new Promise((resolve,reject)=>{
  setTimeout(()=>{
    // resolve("p2成功")
    reject("p2失败")
  },1000)
})
let p3 = "p3 字符串"

Promise.all2([p1,p2,p3]).then((res)=>{
  console.log(res)
}).catch((err)=>{
  console.log(err)
})