手写Promise的原型方法和静态方法

手写Promise的原型方法和静态方法

说起Promise大家应该都耳熟能详,我们今天来看下Promise的相关方法

有如下:

  • 原型方法:then、catch、finally

  • 静态方法:resolve、reject、race、all、allSettled、any

手写实现方法如下:

实现resolve方法

promise.resolve(‘123’)

实质上就是

new Promise(resolve=>{

resolve(‘123’)

})

Promise.resolve(value)  将给定的一个值转为Promise对象。

  • 如果这个值是一个 promise ,那么将返回这个 promise ;
  • 如果这个值是thenable(即带有”then” 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;
  • 否则返回的promise将以此值完成,即以此值执行resolve()方法 (状态为fulfilled)。
 class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }
        //value 要解析为 Promise 对象的值
        static resolve(value) {
          //如果是
          if (value instanceof MyPromise) {
            return value
          } else if (value && typeof value === 'object' && 'then' in value) {
            return new MyPromise((resolve, reject) => {
              value.then(resolve, reject)
            })
          }
          return new MyPromise((resolve) => {
            resolve(value)
          })
        }
      }
      const promise1 = MyPromise.resolve(123)

      promise1.then((value) => {
        console.log(value)
        // expected output: 123
      })

      // Resolve一个thenable对象
      var p1 = MyPromise.resolve({
        thenfunction (onFulfill{
          onFulfill('Resolving')
        },
      })
      console.log(p1 instanceof MyPromise) // true, 这是一个Promise对象

      setTimeout(() => {
        console.log('p1 :>> ', p1)
      }, 1000)

      p1.then(
        function (v{
          console.log(v) // 输出"Resolving!"
        },
        function (e{
          // 不会被调用
        }
      )

      // Thenable在callback之前抛出异常
      // MyPromise rejects
      var thenable = {
        thenfunction (resolve{
          throw new TypeError('Throwing')
          resolve('Resolving')
        },
      }

      var p2 = MyPromise.resolve(thenable)
      p2.then(
        function (v{
          // 不会被调用
        },
        function (e{
          console.log(e) // TypeError: Throwing
        }
      )
手写Promise的原型方法和静态方法

实现reject方法

const p=Promise.reject(‘error’)

相当于下方函数:

const p=new Promise(reject=>{

reject(‘11111’)

})

Promise.reject() 方法返回一个带有拒绝原因的Promise对象。

 class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }
        //error 要解析为 Promise reject的值
        static reject(error) {
          return new MyPromise((resolve, reject) => {
            reject(error)
          })
        }
      }
      MyPromise.reject(new Error('fail')).then(
        function ({
          // not called
        },
        function (error{
          console.error(error) // Error: fail
        }
      )
手写Promise的原型方法和静态方法

实现Promise.prototype.catch方法

catch() 方法返回一个Promise,并且处理拒绝的情况,用于指定发生错误时的回调函数。

它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。

class MyPromise {
 static PENDING = 'pending'
 static FULFILLED = 'fulfilled'
 static REJECTED = 'rejected'
 constructor(executor) {
  this.PromiseState = MyPromise.PENDING
  this.PromiseResult = null
  this.fulfilledCallBacks = []
  this.rejectedCallBacks = []
  try {
   executor(this.resolve.bind(this), this.reject.bind(this))
  } catch (error) {
   this.reject(error)
  }
 }
 resolve(result) {
  if ((this.PromiseState = MyPromise.PENDING)) {
   setTimeout(() => {
    this.PromiseState = MyPromise.FULFILLED
    this.PromiseResult = result
    for (const callBack of this.fulfilledCallBacks) {
     callBack(result)
    }
   })
  }
 }
 reject(reason) {
  if ((this.PromiseState = MyPromise.PENDING)) {
   setTimeout(() => {
    this.PromiseState = MyPromise.REJECTED
    this.PromiseResult = reason
    for (const callBack of this.rejectedCallBacks) {
     callBack(reason)
    }
   })
  }
 }
 then(onFulfilled, onRejected) {
  onFulfilled =
   typeof onFulfilled === 'function' ? onFulfilled : (val) => val
  onRejected =
   typeof onRejected === 'function'
   ? onRejected
   : (err) => {
    throw err
   }
  return new MyPromise((resolve, reject) => {
   if (this.PromiseState === MyPromise.PENDING) {
    this.fulfilledCallBacks.push(() => {
     setTimeout(() => {
      let x = onFulfilled(this.PromiseResult)
      x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
     })
    })
    this.rejectedCallBacks.push(() => {
     setTimeout(() => {
      let x = onRejected(this.PromiseResult)
      x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
     })
    })
   } else if (this.PromiseState === MyPromise.FULFILLED) {
    try {
     setTimeout(() => {
      let x = onFulfilled(this.PromiseResult)
      x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
     })
    } catch (error) {
     reject(error)
    }
   } else {
    try {
     setTimeout(() => {
      let x = onRejected(this.PromiseResult)
      x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
     })
    } catch (error) {
     reject(error)
    }
   }
  })
 }
 catch(onRejected) {
  return this.then(undefined, onRejected)
 }
}

// 捕获异常
const p2 = new MyPromise(function (resolve, reject{
 throw new Error('test')
})
p2.catch(function (error{
 console.log(error) //Error: test
})

实现 Promise.prototype.finally

finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。

由于无法知道promise的最终状态,所以 finally 的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。

   class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }
        finally(callBack) {
          return this.then(callBack, callBack)
        }
      }

      // 捕获异常
      let p1 = new MyPromise(function (resolve, reject{
        resolve(1)
      }).finally(function ({
          console.log('finally'// finally
        })

实现 Promise.all

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 输入的所有promise的resolve回调的结果是一个数组。

  • Promise.all 等待所有都完成(或第一个失败)
  • 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
  • 如果参数中包含非 promise 值,这些值将被忽略,但仍然会被放在返回数组中,如果 promise 完成的话 (也就是如果参数里的某值不是Promise,则需要原样返回在数组里)
  • 在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值)。
  • 如果传入的 promise 中有一个失败(rejected),Promise.all 异步地将失败的那个结果给失败状态的回调函数,而不管其它 promise 是否完成
class MyPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  constructor(executor) {
    this.PromiseState = MyPromise.PENDING
    this.PromiseResult = null
    this.fulfilledCallBacks = []
    this.rejectedCallBacks = []
    try {
      executor(this.resolve.bind(this), this.reject.bind(this))
    } catch (error) {
      this.reject(error)
    }
  }
  resolve(result) {
    if ((this.PromiseState = MyPromise.PENDING)) {
      setTimeout(() => {
        this.PromiseState = MyPromise.FULFILLED
        this.PromiseResult = result
        for (const callBack of this.fulfilledCallBacks) {
          callBack(result)
        }
      })
    }
  }
  reject(reason) {
    if ((this.PromiseState = MyPromise.PENDING)) {
      setTimeout(() => {
        this.PromiseState = MyPromise.REJECTED
        this.PromiseResult = reason
        for (const callBack of this.rejectedCallBacks) {
          callBack(reason)
        }
      })
    }
  }
  then(onFulfilled, onRejected) {
    onFulfilled =
      typeof onFulfilled === 'function' ? onFulfilled : (val) => val
    onRejected =
      typeof onRejected === 'function'
      ? onRejected
      : (err) => {
        throw err
      }
    return new MyPromise((resolve, reject) => {
      if (this.PromiseState === MyPromise.PENDING) {
        this.fulfilledCallBacks.push(() => {
          setTimeout(() => {
            let x = onFulfilled(this.PromiseResult)
            x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
          })
        })
        this.rejectedCallBacks.push(() => {
          setTimeout(() => {
            let x = onRejected(this.PromiseResult)
            x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
          })
        })
      } else if (this.PromiseState === MyPromise.FULFILLED) {
        try {
          setTimeout(() => {
            let x = onFulfilled(this.PromiseResult)
            x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
          })
        } catch (error) {
          reject(error)
        }
      } else {
        try {
          setTimeout(() => {
            let x = onRejected(this.PromiseResult)
            x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
          })
        } catch (error) {
          reject(error)
        }
      }
    })
  }

  //value 要解析为 Promise 对象的值
  static resolve(value) {
    //如果是
    if (value instanceof MyPromise) {
      return value
    } else if (value && typeof value === 'object' && 'then' in value) {
      return new MyPromise((resolve, reject) => {
        value.then(resolve, reject)
      })
    }
    return new MyPromise((resolve) => {
      resolve(value)
    })
  }
  static all(promiseList) {
    if (Array.isArray(promiseList)) {
      return new MyPromise((resolve, reject) => {
        if (promiseList.length === 0) {
          resolve(promiseList)
        }
        let count = 0
        let result = []
        promiseList.forEach((item, index) => {
          if (item instanceof MyPromise) {
            MyPromise.resolve(item).then(
              (res) => {
                count++
                result[index] = res
                count === promiseList.length && resolve(result)
              },
              (error) => {
                reject(error)
              }
            )
          } else {
            count++
            result[index] = item
            count === promiseList.length && resolve(result)
          }
        })
      })
    } else {
      throw TypeError('argument must be Array')
    }
  }
}

// 捕获异常

const promise1 = MyPromise.resolve(3)
const promise2 = 42
const promise3 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(100)
  })
})

MyPromise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values)
})
// [3, 42, 100]

实现Promise.allSettled

Promise.allSettled(iterable) 方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

  • 当你有多个彼此不依赖的异步任务成功完成时,或者你总是想知道每个promise的结果时,通常使用它。
  • 相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。

参数 iterable 是一个可迭代的对象,例如Array,其中每个成员都是Promise。

对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。

举个🌰:

let p1=Promise.resolve(1)
let p2=Promise.reject(2)
let p3=Promise.resolve(3)
let p4=Promise.reject(4)
Promise.allSettled([p1,p2,p3,p4]).then(res=>{
 console.log(res)
})
 //返回了一个数组
 [{status'fulfilled'value1},
{status'rejected'reason2},
{status'fulfilled'value3},
{status'rejected'reason4}]
 class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }

        //value 要解析为 Promise 对象的值
        static resolve(value) {
          //如果是
          if (value instanceof MyPromise) {
            return value
          } else if (value && typeof value === 'object' && 'then' in value) {
            return new MyPromise((resolve, reject) => {
              value.then(resolve, reject)
            })
          }
          return new MyPromise((resolve) => {
            resolve(value)
          })
        }
        static allSettled(promiseList) {
          if (Array.isArray(promiseList)) {
            return new MyPromise((resolve, reject) => {
              let count = 0
              let result = []
              // 如果传入的是一个空数组,那么就直接返回一个resolved的空数组promise对象
              if (promiseList.length === 0) {
                return resolve(promiseList)
              }
              promiseList.forEach((item, index) => {
                  MyPromise.resolve(item).then(
                    (res) => {
                      count++
                      result[index] = {
                        status: MyPromise.FULFILLED,
                        value: res,
                      }
                      count === promiseList.length && resolve(result)
                    },
                    (error) => {
                      count++
                      result[index] = {
                        status: MyPromise.REJECTED,
                        reason: error,
                      }
                      count === promiseList.length && resolve(result)
                    }
                  )
              })
            })
          } else {
            throw TypeError('argument must be Array')
          }
        }
      }

      // 测试代码

      const promise1 = MyPromise.resolve(3)
      const promise2 = 1
      const promises = [promise1, promise2]

      MyPromise.allSettled(promises).then((results) =>
        results.forEach((result) => console.log(result))
      )

      setTimeout(() => {
        const p1 = MyPromise.resolve(3)
        const p2 = new MyPromise((resolve, reject) =>
          setTimeout(reject, 100'foo')
        )
        const ps = [p1, p2]

        MyPromise.allSettled(ps).then((results) =>
          results.forEach((result) => console.log(result))
        )
      }, 1000)

      MyPromise.allSettled([]).then((results) => console.log(results))
//打印结果
(0) []
{status'fulfilled'value3}
{status'fulfilled'value1}
{status'fulfilled'value3}
{status'rejected'reason'foo'}

实现Promise.any

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。

如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。

  • 如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise。
  • 如果传入的参数不包含任何 promise,则返回一个 异步完成 (asynchronously resolved)的 Promise。(将非Promise值,转换为Promise并当做成功)
  • 只要传入的迭代对象中的任何一个 promise 变成成功(resolve)状态,或者其中的所有的 promises 都失败,那么返回的 promise 就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。(如果所有Promise都失败,则报错)
 class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }
        catch(onRejected) {
          return this.then(undefined, onRejected)
        }
        //value 要解析为 Promise 对象的值
        static resolve(value) {
          //如果是
          if (value instanceof MyPromise) {
            return value
          } else if (value && typeof value === 'object' && 'then' in value) {
            return new MyPromise((resolve, reject) => {
              value.then(resolve, reject)
            })
          }
          return new MyPromise((resolve) => {
            resolve(value)
          })
        }
        static any(promiseList) {
          if (Array.isArray(promiseList)) {
            return new MyPromise((resolve, reject) => {
              let count = 0
              let errors = []
              // 注意注意:如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise。
    if (promiseList.length === 0return reject(new AggregateError('All promises were rejected'));
              promiseList.forEach((item, index) => {
                MyPromise.resolve(item).then(
                  (res) => {
                    resolve(res)
                  },
                  (reason) => {
                    count++
                    errors.push(reason)
                    /**
+                            * 如果可迭代对象中没有一个 promise 成功,就返回一个失败的 promise 和AggregateError类型的实例,
+                            * AggregateError是 Error 的一个子类,用于把单一的错误集合在一起。
+                            */

                    count === promiseList.length &&
                      reject(new AggregateError(errors))
                  }
                )
              })
            })
          } else {
            throw TypeError('argument must be Array')
          }
        }
      }

      // 测试代码

      MyPromise.any([]).catch((e) => {
        console.log(e)
      })

      const pErr = new Promise((resolve, reject) => {
        reject('总是失败')
      })

      const pSlow = new Promise((resolve, reject) => {
        setTimeout(resolve, 500'最终完成')
      })

      const pFast = new Promise((resolve, reject) => {
        setTimeout(resolve, 100'很快完成')
      })

      Promise.any([pErr, pSlow, pFast]).then((value) => {
        console.log(value)
        // 期望输出: "很快完成"
      })

      const pErr1 = new MyPromise((resolve, reject) => {
        reject('总是失败')
      })

      const pErr2 = new MyPromise((resolve, reject) => {
        reject('总是失败')
      })

      const pErr3 = new MyPromise((resolve, reject) => {
        reject('总是失败')
      })

      MyPromise.any([pErr1, pErr2, pErr3]).catch((e) => {
        console.log(e)
      })
      //打印结果
//       AggregateError: All promises were rejected
// AggregateError: All promises were rejected
// 很快完成

实现race方法

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的返回值,从而异步地解析或拒绝(一旦堆栈为空)。

race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。

  • 如果传的迭代是空的,则返回的 promise 将永远等待。
  • 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。
  class MyPromise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(executor) {
          this.PromiseState = MyPromise.PENDING
          this.PromiseResult = null
          this.fulfilledCallBacks = []
          this.rejectedCallBacks = []
          try {
            executor(this.resolve.bind(this), this.reject.bind(this))
          } catch (error) {
            this.reject(error)
          }
        }
        resolve(result) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.FULFILLED
              this.PromiseResult = result
              for (const callBack of this.fulfilledCallBacks) {
                callBack(result)
              }
            })
          }
        }
        reject(reason) {
          if ((this.PromiseState = MyPromise.PENDING)) {
            setTimeout(() => {
              this.PromiseState = MyPromise.REJECTED
              this.PromiseResult = reason
              for (const callBack of this.rejectedCallBacks) {
                callBack(reason)
              }
            })
          }
        }
        then(onFulfilled, onRejected) {
          onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (val) => val
          onRejected =
            typeof onRejected === 'function'
              ? onRejected
              : (err) => {
                  throw err
                }
          return new MyPromise((resolve, reject) => {
            if (this.PromiseState === MyPromise.PENDING) {
              this.fulfilledCallBacks.push(() => {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              })
              this.rejectedCallBacks.push(() => {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              })
            } else if (this.PromiseState === MyPromise.FULFILLED) {
              try {
                setTimeout(() => {
                  let x = onFulfilled(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                })
              } catch (error) {
                reject(error)
              }
            } else {
              try {
                setTimeout(() => {
                  let x = onRejected(this.PromiseResult)
                  x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                })
              } catch (error) {
                reject(error)
              }
            }
          })
        }
        catch(onRejected) {
          return this.then(undefined, onRejected)
        }
        //value 要解析为 Promise 对象的值
        static resolve(value) {
          //如果是
          if (value instanceof MyPromise) {
            return value
          } else if (value && typeof value === 'object' && 'then' in value) {
            return new MyPromise((resolve, reject) => {
              value.then(resolve, reject)
            })
          }
          return new MyPromise((resolve) => {
            resolve(value)
          })
        }
        static race(promiseList) {
          if (Array.isArray(promiseList)) {
            return new MyPromise((resolve, reject) => {
              // 注意注意:如果传入的参数是一个空的可迭代对象,则永远为pending状态
              if (promiseList.length > 0) {
                promiseList.forEach((item, index) => {
                  /**
                   * 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,
                   * 则 Promise.race 将解析为迭代中找到的第一个值。
                   */

                  MyPromise.resolve(item).then(resolve, reject)
                })
              }
            })
          } else {
            throw TypeError('argument must be Array')
          }
        }
      }

      // 测试代码

      /**
       * 验证Promise.race()方法
       */


      // 数组全是非Promise值,测试通过
      let p1 = Promise.race([134])
      setTimeout(() => {
        console.log('p1 :>> ', p1) //1
      })

      // 空数组,测试通过
      let p2 = Promise.race([])
      setTimeout(() => {
        console.log('p2 :>> ', p2) //pengding
      })

      //  p1 :>>  Promise {<fulfilled>: 1}
      //   p2 :>>  Promise {<pending>}

总结:

Promise方法 总结 传递[]数组影响
all() 参数所有结果为成功才执行then方法返回结果,否则catch方法为第一个rejected的Promise 返回一个已完成(already resolved)状态的 Promise(resolve([]))
allSettled() 不管Promise的结果是否成功,都要等结果返回完毕之后执行then方法
race() 只要有一个Promise有了结果,就决定了最终新Promise的状态 一直处于pending状态
any() 只要有一个Promise为成功,就会这个成功Promise的结果,如果所有Promise为失败,那么最终新Promise的状态为rejected且报错 Promise的状态为rejected且报错(AggregateError)
finally() 不管Promise对象无论变成fulfilled还是reject状态,最终都会被执行的代码

文章出自:https://juejin.cn/post/7143564273040490503

作者:Trap_


原文始发于微信公众号(前端24):手写Promise的原型方法和静态方法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/216684.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!