如何手动实现一个promise(简单版)

110 阅读1分钟

1.简单了解promise

- 三种状态
   - 1.pending : 等待状态
   - 2.fulfilled  : Promise的异步操作已经成功结束成功
   * 3.rejected: Promise的异步操作未成功结束,可能是一个错误,或者其他原因

2.实现

// 手写一个简单功能不完善的promise(因为实力只能做到这一步)
    class MyPromise {
    
      // 定义promise的三种状态
      static PENDING = 'pending'
      static FULFILLED = 'fulfilled'
      static REJECTED = 'rejected'

      // 定义初始状态
      state = MyPromise.PENDING

      // 暴露参数
      value
      reason

      // 定义两个数组作为异步执行时then里面函数的缓存点
      resolveFnList = []
      rejectFnList = []

      constructor(execute) {
      
        // 定义resolve/reject,
        // 在调用时完成value/reason暴露,
        // 改变promise的状态为fuifilled/rejected,
        // 执行异步之后缓存的函数    
        // 因为promise的状态是凝固的,所以要先进行判断状态为pending是才执行
        // value/reason为用户调用函数时传过来的参数
        
        let resolve = value => {
          if (this.state === MyPromise.PENDING) {
            this.value = value
            this.state = MyPromise.FULFILLED
            this.resolveFnList.forEach(fn => fn(value))
          }
        }
        
        let reject = reason => {
          if (this.state === MyPromise.PENDING) {
            this.reason = reason
            this.state = MyPromise.REJECTED
            this.rejectFnList.forEach(fn => fn(reason))
          }
        }
        
        // 在传入的execute函数里面传入resolve,reject两个函数
        execute(resolve, reject)
      }
      
      // 模拟then方法 传入onResolveFn接受value,onRejectFn接受reason
      then(onResolveFn, onRejectFn) {
      
        // 根据不同状态执行函数
        switch (this.state) {
          case MyPromise.FULFILLED:
            onResolveFn && onResolveFn(this.value)
            break
          case MyPromise.REJECTED:
            onRejectFn && onRejectFn(this.reason)
            break
          case MyPromise.PENDING:
            onResolveFn && this.resolveFnList.push(onResolveFn)
            onRejectFn && this.rejectFnList.push(onRejectFn)
            break
        }
      }
    }

     //进行调用
    let p = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve(777) //reject()
      }, 1000)
    })
    
    p.then(res => {
      console.log(res)
    },rej=>{
      console.log(rej)
    })