JS高级之-——自己实现基本的Promise类

学习JS高级练习一篇

const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

class XYPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING
    this.value = undefined
    this.reason = undefined

    this.onfulfilledfns = []
    this.onrejectfns = []

    const resolve = (value) => {
      queueMicrotask(() => {
        if(this.status !== PROMISE_STATUS_PENDING) return
        this.status = PROMISE_STATUS_FULFILLED
        this.value = value
        this.onfulfilledfns.forEach((fn) => {
          fn(this.value)
        })
      })
    }

    const reject = (value) => {
      queueMicrotask(() => {
        if(this.status !== PROMISE_STATUS_PENDING) return
        this.status = PROMISE_STATUS_REJECTED
        this.reason = value
        this.onrejectfns.forEach((fn) => {
          fn(this.reason)
        })
      })
    }

    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }

  then(onfulfilled, onrejected) {
    return new XYPromise((resolve, reject) => {
      // 没有传函数时的默认函数
      const defaultOnfulfilled = (res) => {
        return res
      }
      const defaultOnrejected = (err) => {
        throw err
      }
      onfulfilled = onfulfilled || defaultOnfulfilled
      onrejected = onrejected || defaultOnrejected

      if (this.status === PROMISE_STATUS_FULFILLED) {

        try {
          const value = onfulfilled(this.value)
          resolve(value)
        } catch (err) {
          reject(err)
        }
      }

      if (this.status === PROMISE_STATUS_REJECTED) {
        
        try {
          const value = onrejected(this.reason)
          resolve(value)
        } catch (err) {
          reject(err)
        }
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onfulfilledfns.push(() => {
          try {
            const value = onfulfilled(this.value)
            resolve(value)
          } catch (err) {
            reject(err)
          }
        })

        this.onrejectfns.push(() => {
          try {
            const value = onrejected(this.reason)
            resolve(value)
          } catch (err) {
            reject(err)
          }
        })
      }
    })
  }

  catch(onrejected) {
    return this.then(undefined, onrejected)
  }

  finally(onfinally) {
    this.then(()=>{
      onfinally()
    }, () => {
      onfinally()
    })
  }

  static resolve (value) {
    return new XYPromise(resolve => {
      resolve(value)
    })
  }

  static reject (value) {
    return new XYPromise((resolve, reject) => {
      reject(value)
    })
  }

  static all (promises) {
    return new XYPromise((resolve, reject) => {
      const results = []
      promises.forEach(p => {
        p.then(res => {
          results.push(res)
          if(results.length === promises.length) {
            resolve(results)
          }
        }, err => {
          reject(err)
        })
      })
    })
  }

  static allSettled (promises) {
    return new XYPromise((resolve, reject) => {
      const results = []
      promises.forEach(p => {
        p.then(res => {
          results.push({
            status: PROMISE_STATUS_FULFILLED,
            value: res
          })
          if(results.length === promises.length) {
            resolve(results)
          }
        }, err => {
          results.push({
            status: PROMISE_STATUS_REJECTED,
            reason: err
          })
          if(results.length === promises.length) {
            resolve(results)
          }
        })
      })
    })
  }

  static race (promises) {
    return new XYPromise((resolve, reject) => {
      promises.forEach(p =>{
        p.then(res => {
          resolve(res)
        }, err => {
          reject(err)
        })
      })
    })
  }

  static any (promises) {
    return new XYPromise((resolve, reject) => {
      const errs = []
      promises.forEach(p=> {
        p.then(res =>{
          resolve(res)
        }, err => {
          errs.push(err)
          if(errs.length === promises.length) {
            reject( new AggregateError(errs) )
          }
        })
      })
    })
  }
}

// const promise = new XYPromise((resolve, reject) => {
//   resolve('111')
//   // reject('err msg')
//   throw new Error('err!!!!')
// })

// promise.then(res => {
//   console.log('res1', res)
//   return '2222'
// }).catch(err => {
//   console.log('err1', err)
//   return '2222'
// }).then(res2=>{
//   console.log('err2', res2)
// }).finally(() => {
//   console.log('finally')
// })

// const p666 = XYPromise.reject('663336')

// p666.then(res=>{
//   console.log('666res', res)
// }).catch(err =>{
//   console.log('666err', err)
// }).finally(() =>{
//   console.log('finally')
// })

const p1 = new XYPromise((resolve, reject) => {
  setTimeout(()=>{
    // resolve('111')
    // reject('err msg1')
    throw new Error('err!!!!')
  }, 1000)
})

const p2 = new XYPromise((resolve, reject) => {
  setTimeout(()=>{
    // resolve('222')
    reject('err msg2')
    // throw new Error('err!!!!')
  }, 2000)
})

const p3 = new XYPromise((resolve, reject) => {
  setTimeout(()=>{
    resolve('333')
    reject('err msg3')
    // throw new Error('err!!!!')
  }, 3000)
})

const p = XYPromise.any([p1,p2,p3])
.then(res=>{
  console.log('res1', res)
}).catch(err=>{
  console.log('err1', err.errors)
}).finally(() =>{
  console.log('finally')
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值