题目:Promise.all的polyfill(可以使用Promise)

108 阅读1分钟

用法

  const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p1')
      resolve(1000)
    }, 1000)
  })
  const p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p4')
      resolve(300)
    }, 300)
  })
  const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p2')
      reject(new Error(500))
    }, 500)
  })
  const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p3')
      reject(new Error(100)) 
    }, 100)
  })
  Promise.all([
    p1,
    p2,
    p3
  ]).then((data) => {
    // 数据的顺序与传入数组的Promise顺序一致
    console.log(data)
  }).catch((err) => {
    // 虽然p2先传入但是后执行
    // p3先reject 最终reject p3的错误 捕获后就结束了
    console.log(err)
  })
  /* 
  p3 
  Error: 500
  p2
  p1
  */

polyfill

/* 
  思路:
  myPromiseAll 函数 传入Promise数组,返回Promise对象 (有then和catch方法)
  如果数组中所有Promise状态都变成fullfilled 则then方法中输出resolve出的数据,所有数据在一个数组中,数组中数据顺序与传入Promise顺序一致
  如果数组中有一个Promise的状态变成rejected 则catch方法中捕获到最早抛出的异常
  */
  const myPromiseAll = (arr) => {
    return new Promise((resolve, reject) => {
      const result = []
      arr.forEach((item, index) => {
        item.then(data => {
          result.push({[index]: data})
          if (result.length === arr.length) {
            console.log(result)
            const data = []
            result.forEach(value => {
              data[Object.keys(value)[0]] = Object.values(value)[0]
            })
            resolve(data)
          }
        }).catch(err => {
          reject(err)
        })
      })
    })
  }

// 测试代码
  const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p1')
      resolve(1000)
    }, 1000)
  })
  const p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p4')
      resolve(300)
    }, 300)
  })
  const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p2')
      reject(new Error(500))
    }, 500)
  })
  const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('p3')
      reject(new Error(100)) 
    }, 100)
  })

  /* myPromiseAll([Promise.resolve(1), Promise.resolve(2)]).then(data => {
    console.log(data)
  }) */
  /* myPromiseAll([p1, p4]).then(data => {
    console.log(data)
  }) */
  /* myPromiseAll([p2, p3]).then(data => {
    console.log(data)
  }).catch(err => {
    console.log(err)
  }) */
  myPromiseAll([p1, p4]).then(data => {
    console.log(data) // [1000, 300]
  }).catch(err => {
    console.log(err)
  })
  /* myPromiseAll([Promise.resolve(1), Promise.reject(2)]).then(data => {
    console.log(data)
  }).catch(err => {
    console.log(err)
  }) */