Promise 高频知识点之all,any,race,allSettled的实现

150 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

Promise使用

new Promise(executor) 实例promise对象的时候传进去了一个执行函数executorexecutor 两个参数分别是resolverejectresolve用来将PENDING 改为FULFILLED 的, reject 是将PENDING 改为REJECTED resolve参数值就是promise的返回值。

then方法的逻辑就是当resolve没执行的时候,也就是状态没变,还是PENDING的时then方法实际做的是successCallbackfailCallback回调的收集,只有状态不为PENDING才会根据状态执行对应的回调successCallbackfailCallback

const value = new Promise((resolve, reject) => {
  // setTimeout 就相当于耗时的接口请求 
  setTimeout(() => {resolve('23')}, 0)
})


value.then(successCallback, failCallback)

const successCallback = (res) => {
   console.log('成功的回调')
}

const failCallback = (err) => {
   console.log('失败的回调')
}

实际上面的拆分就是我们平时接口请求的如下代码

new Promise((resolve, reject) => {
  // setTimeout 就相当于耗时的接口请求 
  setTimeout(() => {resolve('23')}, 0)
}).then((res) => {
   console.log('成功的回调')
}, (err) => {
   console.log('失败的回调')
})

Promise.resolve(value)的实现

该方法实际上是快速创建Promise对象,实际返回的就是new Promise(value)将value值传递给then方法

  • 源码实现
Promise.resolve = function (value) {
    if (value instanceof  Promise) return value
    return new Promise(resolve => resolve(value))
}

Promise 高频知识点之allanyraceallSettled的实现

Promise.all方法的实现

  • 使用方法

传一个promise数组进去,全部成功才会走到then回调中, 否则都会到catche方法

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

  • 源码实现 由于传进来的promiseArray 都是可能耗时操作。只有p1,p2,p3执行完了,他们对应的then方法才会执行,then方法里面判断数组和传进来长度一致证明全部执行完了,调最终的resolveall方法的then成功回调successCallback才会执行另外只要有一个失败,直接调用了最外层的reject方法,all方法执行结束
Promise.all = function (promiseArray) {
    let array = []
    return new Promise((resolve, reject) => {
      promiseArray.forEach((value, index) => {
          // p1,p2,p3 三个promise都会有对应的 Promise.resolve(p) 就相当于传值操作。等到p1,p2, p3 执行完了后才会走对应的then里面的成功回调successCallback 
          Promise.resolve(value).then((result) => {
              array[index] = result
              if (array.length === promiseArray.length) {
                  resolve(array)
              }
          }, reject)
      })  
    })
}

Promise.race 的实现

race 赛跑, 任意一个promise状态结束就返回,成功或者失败

  • 使用
Promise.race([p1,p2,p3]).then(console.log).catch(console.log)

  • 实现
Promise.race = function (promiseArray) {
    return new Promise(function (resolve, reject) {
        promiseArray.forEach(item => Promise.resolve(item).then(resolve,reject))
    })
}

Promise.any 的实现

只有一个成功就成功,所有失败才失败. 就是promise.all的resole和reject逻辑互换

Promise.allSettled

相当于all和any 的结合,所有的都走完了才会回调,也就是允许中间可能有失败

  • 源码
Promise.MyAllSettled = function (promises) {
  let arr = [],
    count = 0
  return new Promise((resolve, reject) => {
    promises.forEach((item, i) => {
      Promise.resolve(item).then(res => {
        arr[i] = { status: 'fulfilled', val: res }
        count += 1
        if (count === promises.length) resolve(arr)
      }, (err) => {
        arr[i] = { status: 'rejected', val: err }
        count += 1
        if (count === promises.length) resolve(arr)
      })
    })
  })
}