手写系列 - all、race、any

132 阅读2分钟

all

Promise.all可以将多个Promise实例包装成一个新的Promise实例;

同时,整个Promise数组在成功和失败的返回值是不同的:

  • Promise序列会全部执行通过才认为是成功,否则认为是失败;
  • 当所有Promise都成功时,返回一个结果数组;
  • 只要存在一个失败的Promise,则返回最先被reject失败状态的值;
class MyPromise {
  static all(array) {
    let index = 0
    let res = []
    return new Promise((resolve, reject) => {

      function addData(key, value) {
        res[key] = value  //
        index++
        if (index === array.length) {
          resolve(res)
        }

      }

      for (let i = 0; i < array.length; i++) {
        let curr = array[i]
        if (curr instanceof Promise) {
          curr.then(value => addData(i, value), reason => reject(reason))
        } else {
          addData(i, array[i])
        }
      }
    })

  }
}
let p0 = new Promise((resolve, reject) => {
  resolve(0)
})

let p1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(1)
  }, 1000)
})
let p2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(2)
  }, 2000)
})
let p3 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(3)
  }, 3000)
})

MyPromise.all([p3, p1, p2, p0]).then(res => {
  console.log(res) // [3, 1, 2, 0]
})

race

Promse.race就是赛跑的意思,就是说Promise.race([p1, p2, p3…])中哪个Promise的结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态;

总结来说就是:

  • Promise序列中第一个执行完毕的是通过,则认为成功,如果第一个执行完毕的Promise是拒绝,则认为失败;(即只看第一个执行完毕的Promise);

class MyPromise {
  static race(array) {
    return new Promise((resolve, reject) => {
      for (let i = 0; i < array.length; i++) {
        let curr = array[i]
        if (curr instanceof MyPromise) {
          curr.then(resolve, reject)
        } else {
          resolve(curr)
        }
      }
    })

  }
}
 
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('1')
  }, 0)

})
let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('2')
  }, 1000)

})
let p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('3')
  }, 2000)

})


MyPromise.race([p3, p1, p2]).then(res => {
  console.log(res);
})

any

和All方法类似,Any也是接收一个Promise数组;

同时,整个Promise数组在成功和失败的返回值也是不同的:

  • Promise序列只要有一个执行通过,则认为成功,如果全部拒绝,则认为失败;
class MyPromise {

  // 一个成功则返回
  // 全部失败,才会返回
  static any(array) {
    let index = 0
    let res = []
    return new Promise((resolve, reject) => {
      function addData(key, value) {
        res[key] = value
        index++
        if (index === array.length) {
          reject(res)
        }

      }


      for (let i = 0; i < array.length; i++) {
        let curr = array[i]
        if (curr instanceof Promise) {
          curr.then(resolve, reason => addData(i, reason))
        } else {
          resolve(curr)
        }
      }

    })

  }
}

const p1 = new Promise((resolve, reject) => {
  resolve("1")

})
const p2 = new Promise((resolve, reject) => {
  reject("2")

})
const p3 = new Promise((resolve, reject) => {
  reject("3")

})
const p4 = new Promise((resolve, reject) => {
  reject("4")

})

MyPromise.any([p1, p2, p3, p4]).then(res => {
  console.log(res); //1
}, reason => {
  console.log(reason)
})

MyPromise.any([p2, p3, p4]).then(res => {
  console.log(res);
}, reason => {
  console.log(reason) //[ '2', '3', '4' ]
})