• 自己实现一个Promise库


    源码地址

    1. 先看基本使用

      const promise = new Promise((resolve, reject) => {
        resolve(value)
        // or reject(reason)
      })
      

      创建Promise时传入的回调函数是立即执行的,所以我们的Promise应该是这样(用ts实现)

      function BDuckPromise(fn: (resolve: (value: any) => void, reject: (reason: any) => void) => any) {
        
        function resolve(value: any) {
          
        }
        
        function reject(reason: any) {
          
        }
        
        fn(resolve, reject);
        
      }
      
    2. 每个Promise对象都有三种生命状态:PENDING(未开始)、FULFILLED(已完成)、REJECTED(已失败)。生命状态只能是PENDING => FULFILLED 或者 PENDING => REJECTED 且一旦发生改变不可逆转。此时我们的代码是这样,具有了状态。

      enum STATE {
        PENDING = 0,
        FULFILLED = 1,
        REJECTED = 2
      }
      
      function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) {
        let store = null,
          state = STATE.PENDING
      
      
        function resolve(value: any): void {
          store = value;
          state = STATE.FULFILLED;
        }
        
        function reject(reason: any): void {
          store = reason;
          state = STATE.REJECTED;
        }
      
        fn(resolve, reject)
      }
      
    3. 一个Promise对象回调中传入的值(value)或者拒因(reason)是在该示例对象的then函数中获取的

      promise.then(value => {
        console.log(value);
        return value + 1
      }, reason => {
        // ....
      })
      

      then具有两个回调函数onfulfilled(用于成功时传递value)、onrejected(用于失败时传递reason)

      所以我们then方法大概是长这样子

      function BDuckPromise() {
        this.then = (onfulfilled, onrejected) => {
          if(state === STATE.PENDING) {
            return
          }
      
          if(state === STATE.FULFILLED) {
            onfulfilled(store)
            return
          }
      
          if(state === STATE.REJECTED) {
            onrejected(store)
            return
          }
        }
      }
      

      但是等一下,如果我们写成这个样子当我们调用then的时候就必须要求promise的状态已经发生过改变我们才能获取到value或者reason,这个显然不是我们需要的。但是我们应该要写成什么样呢?分析一下

      当我们调用then时候promise仍然处于pending状态时,我们应该怎么将value或者reason在它状态发生改变是传递出去呢?

      显然,我们应该在状态发生改变时调用对应的onfulfilled或者onrejected回调。

      那么我们就应该在状态为pending时将回调函数都存储起来,一旦状态改变了,就调用这些回调函数,这下就清楚了,应当在resolve或者reject中调用我们的onfulfilled或者onrejected回调

      enum STATE {
        PENDING = 0,
        FULFILLED = 1,
        REJECTED = 2
      }
      
      function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) {
        let store = null,
          state = STATE.PENDING,
          callbacks = [];
        
        function resolve(value: any): void {
          store = value;
          state = STATE.FULFILLED;
          callbacks.forEach(callback => {
            if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) {
              callback.onfulfilled(store)
            }
          });
      		callbacks = null
        };
        
        function reject(reason: any): void {
          store = reason;
          state = STATE.REJECTED;
          callbacks.forEach(callback => {
            if(callback.onrejected && 'function' === typeof callback.onrejected) {
              callback.onrejected(store)
            }
          });
      		callbacks = null
        };
      
        this.then = (onfulfilled, onrejected) => {
          if(state === STATE.PENDING) {
            callbacks.push({
              onfulfilled,
              onrejected
            })
            return
          }
      
          if(state === STATE.FULFILLED) {
            onfulfilled(store)
            return
          }
      
          if(state === STATE.REJECTED) {
            onrejected(store)
            return
          }
        };
        fn(resolve, reject)
      }
      
    4. then函数是有返回值的,且返回的的是一个新的Promise对象,所以还得改=_=!

      const promise1 = new Promise((resolve, reject) => {
        resolve(1)
      })
      // promise2 是一个新的Promise对象
      const promise2 = promise1.then(value => {
        return value + 1
      })
      

      现在改成这样子

      this.then = (onfulfilled, onrejected) => {
          return new BDuckPromise((_resolve, _reject) => {
            if(state === STATE.PENDING) {
              callbacks.push({
                onfulfilled,
                onrejected
              })
              return
            }
        
            if(state === STATE.FULFILLED) {
              onfulfilled(store)
              return
            }
        
            if(state === STATE.REJECTED) {
              onrejected(store)
              return
            }
          });
        }
      
    5. 上一个then函数中return的值会传递给下一个then中作为值

      const promise1 = new Promise((resolve, reject) => {
        resolve(1)
      })
      // promise2 是一个新的Promise对象
      const promise2 = promise1.then(value => {
        return value + 1
      })
      .then(value => {
        console.log(value) // 2
      })
      

      好吧,接着改=_=

      this.then = (onfulfilled, onrejected) => {
          return new BDuckPromise((_resolve, _reject) => {
            if(state === STATE.PENDING) {
              callbacks.push({
                onfulfilled,
                onrejected,
                _resolve,
                _reject
              })
              return
            }
        
            if(state === STATE.FULFILLED) {
              const ret = onfulfilled(store)
              _resolve(ret)
              return
            }
        
            if(state === STATE.REJECTED) {
              const ret = onrejected(store)
              _reject(ret)
              return
            }
          });
        }
      
      // 相应的resolve, reject也做相应的更改
      function resolve(value: any): void {
        store = value;
        state = STATE.FULFILLED;
        callbacks.forEach(callback => {
          if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) {
            const ret = callback.onfulfilled(store)
            callback._resolve(ret)
          }
        })
      }
      
      function reject(reason: any): void {
        store = reason;
        state = STATE.REJECTED;
        callbacks.forEach(callback => {
          if(callback.onrejected && 'function' === typeof callback.onrejected) {
            const ret = callback.onrejected(store)
            callback._reject(ret)
          }
        })
      }
      
    6. 如果then中return的是一个新的Promise则下一个then中的value或reason是这个返回的Promise中resolve或者reject中传递value或者reason

      enum STATE {
        PENDING = 0,
        FULFILLED = 1,
        REJECTED = 2
      }
      
      function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) {
        let store:any = null,
          state = STATE.PENDING,
          callbacks:any = []
      
      
        function resolve(value: any): void {
          setTimeout(() => {
            state = STATE.FULFILLED;
            // value 是一个Promise对象
            if(value && 'object' === typeof value && value.then && 'function' === typeof value.then) {
              // do then
              value.then(resolve, reject)
              return
            }
            // value 不是Promise对象
            store = value;
            callbacks.forEach(callback => {
              if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) {
                const ret = callback.onfulfilled(store)
                callback._resolve(ret)
              }
            })
            callbacks = []
          })
        }
        
        function reject(reason: any): void {
          setTimeout(() => {
            state = STATE.REJECTED;
            // value 是一个Promise对象
            if(reason && 'object' === typeof reason && reason.then && 'function' === typeof reason.then) {
              reason.then(resolve, reject)
              return
            }
            // value 不是Promise对象
            store = reason;
            callbacks.forEach(callback => {
              if(callback.onrejected && 'function' === typeof callback.onrejected) {
                const ret = callback.onrejected(store)
                callback._reject(ret)
              }
            })
            callbacks = []
          }, 0)
        }
      
        this.then = (onfulfilled, onrejected) => {
          return new BDuckPromise((_resolve, _reject) => {
            if(state === STATE.PENDING) {
              callbacks.push({
                onfulfilled,
                onrejected,
                _resolve,
                _reject
              })
              return
            }
        
            if(state === STATE.FULFILLED) {
              const ret = onfulfilled(store)
              _resolve(ret)
              return
            }
        
            if(state === STATE.REJECTED) {
              const ret = onrejected(store)
              _reject(ret)
              return
            }
          });
        }
      
        fn(resolve, reject)
      }
      export default BDuckPromise;
      

    还有reject的处理,目前是不合规范的

    大概就是这样,不搞了

  • 相关阅读:
    Java中同步
    Java多线程
    Java中的instanceof关键字
    Java多态与C++中多态的实现
    Java中的接口
    Java中的抽象类
    Java单链表的实现
    Java中的内部类
    memcached telnet command
    The CHECK_POLICY and CHECK_EXPIRATION options cannot be turned OFF when MUST_CHANGE is ON. (Microsoft SQL Server,错误: 15128)
  • 原文地址:https://www.cnblogs.com/zheng-chuang/p/9585883.html
Copyright © 2020-2023  润新知