前端面试自测知识点--手写Promise

手写Promise
手写Promise.resolve , Promise.reject, Promise.all, Promise.race

/**
 * @description 手写Promise
 */

class MyPromise {
  state = 'pending' // 状态 'pending' 'fulfilled' 'rejected'
  value = undefined  // 成功后的值
  reason = undefined // 失败后的值

  resolveCallbacks = [] // pending状态下,成功的回调
  rejectCallbacks = [] // pending状态下,失败的回调


  constructor(fn){
    const resolveHandler = (value) => {
      if(this.state === 'pending'){
        this.state = 'fulfilled'
        this.value = value
        this.resolveCallbacks.forEach(fn => fn(this.value))
      }
    }

    const rejectHandler = (reason) => {
      if(this.state === 'pending'){
        this.state = 'rejected'
        this.reason = reason
        this.rejectCallbacks.forEach(fn => fn(this.reason))
      }
    }

    try {
      fn(resolveHandler, rejectHandler)
    } catch(err) {
      rejectHandler(err)
    }
  }

  then(fn1, fn2){
    // 当 pending状态下, fn1 和 fn2 会被存储到callbacks中
    fn1 = typeof fn1 === "function" ? fn1 : (v) => v
    fn2 = typeof fn2 === "function" ? fn2 : (e) => e

    if(this.state === 'pending'){
      const p1 = new MyPromise((resolve,reject) => {
        this.resolveCallbacks.push(()=>{
          try {
            const newValue = fn1(this.value)
            resolve(newValue)
          } catch(err){
            reject(err)
          }
        })

        this.rejectCallbacks.push(() => {
          try {
            const newReason = fn2(this.Reason)
            reject(newReason)
          } catch(err){
            reject(err)
          }
        })
      })
      return p1
    }

    if(this.state === 'fulfilled'){
      const p1 = new MyPromise((resolve,reject) => {
        try {
          const newValue = fn1(this.value)
          resolve(newValue)
        } catch(err){
          reject(err)
        }
      })
      return p1
    }

    if(this.state === 'rejected'){
      const p1 = new MyPromise((resolve,reject) => {
        try {
          const newReason = fn2(this.reason)
          reject(newReason)
        } catch(err){
          reject(err)
        }
      })
      return p1
    }

  }
 
  // 就是then的语法糖,简单模式
  catch(fn) {
    return this.then(null, fn)
  }
}

MyPromise.resolve = function(value) {
  return new MyPromise((resolve,reject) => {
    resolve(value)
  })
}

MyPromise.reject = function(reason) {
  return new MyPromise((resolve,reject) => {
    reject(reason) 
  })
}

MyPromise.all = function (promiseList = []) {
  const p1 = new MyPromise((resolve,reject) => {
    const result = []
    const length = promiseList.length
    let resolvedCount = 0

    promiseList.forEach((p)=>{
      p.then(data => {
        result.push(data)
        resolvedCount++ // 同理,resolvedCount 必须在then里进行++
        // 这里不能用forEach 的 index来判断 index === length - 1,因为forEach不是一个异步循环,index会一下子增加到最大,而promiseList中的每一个promise还不一定执行完
        if(resolvedCount === length){
          // 已经遍历到最后一个promise
          resolve(result)
        }
      }).catch(err => {
        reject(err)
      })
    })
  })
  return p1
}

MyPromise.race = function(promiseList = []) {
  let resolved = false // 标记
  const p1 = new MyPromise((resolve,reject) => {
    promiseList.forEach(p => {
      p.then(data => {
        if(!resolved){
          resolve(data)
          resolved = true
        }
      }).catch((err) => {
        reject(err)
      })
    })
  })
  return p1
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值