Promise的实现原理

96 阅读1分钟
  <script>
    function Promise(func) {
      const that = this;
      //给Promise对象设置属性status,用于管理状态,初始值为Pending
      that.status = "Pending";
      //给promise对象指定一个用于存储结果数据的属性
      that.data = undefined;
      //每个元素结构:{onResolved(){}, onRejected(){}}
      that.callbacks = [];
      function resolve(value) {
        //如果当前状态不是Pending,直接结束
        if (that.status !== 'pending') {
          return;
        }
        //将状态改为resolved
        that.status = 'resolved';
        //保存value数据
        that.data = value;
        //如果有待执行callback函数,立即异步执行回调
        if (that.callbacks.length > 0) {
          //放入队列中执行所有成功的回调
          setTimeout(() => {
            that.callbacks.forEach(callbacksObj => {
              callbacksObj.onResolved(value);
            });
          });
        }
      }
      function reject(reason) {
        //如果当前状态不是pending,直接结束
        if (that.status !== 'pending') {
          return;
        }
        //将状态改为rejected
        that.status = 'rejected';
        //保存reason数据
        that.data = reason;
        //如果有待执行callback函数,立即异步执行回调
        if (that.callbacks.length > 0) {
          //放入队列中执行所有成功的回调
          setTimeout(() => {
            that.callbacks.forEach(callbacksObj => {
              callbacksObj.onRejected(reason);
            });
          });
        }
      }
      try {
        func(resolve, reject);
      } catch (error) {
        //如果执行器抛出异常,promise对象变为rejected状态
        reject(error);
      }
    }
    Promise.prototype.then = function (onResolved, onRejected) {
      //向后传递成功的value
      onResolved = typeof onResolved === 'function' ? onResolved : value => value;
      //指定默认的失败的回调(实现错误/异常穿透的关键点),向后传递失败的reason
      onRejected =
        typeof onRejected === 'function' ?
          onRejected :
          reason => {
            throw reason;
          };
      const that = this;
      //返回一个新的promise对象
      return new Promise((resolve, reject) => {
        /*指定回调函数处理,根据执行结果,改变return的promise的状态*/
        function handle(callback) {
          /*1. 如果抛出异常,retrun的promise就会失败,reason就是error
            2. 如果回调函数返回不是promise,return的promise就会成功,value就是返回的值
            3. 如果回调函数返回的是promise,return的promise结果就是这个promise的结果*/
          try {
            const result = callback(that.data);
            if (result instanceof Promise) {
              result.then(
                //当result成功时,让return的promise也成功
                //value => resolve(value),
                //当result失败时,让return的promise也失败
                //reason => reject(reason)
                result.then(resolve, reject)
              );
            } else {
              resolve(result);
            }
          } catch (error) {
            reject(error);
          }
        }
        if (that.status === 'pending') {
          //假设当前状态还是PENDING状态,将回调函数保存起来
          that.callbacks.push({
            onResolved(value) {
              handle(onResolved);
            },
            onRejected(reason) {
              handle(onRejected);
            }
          });
        } else if (that.status === 'resolved') {
          //如果当前是resolved状态,异步执行onResolve并改变return的promise状态
          setTimeout(() => {
            handle(onResolved);
          });
        } else {
          //'rejected'
          //如果当前是rejected状态,异步执行onRejected并改变return的promise状态
          setTimeout(() => {
            handle(onRejected);
          });
        }
      });
    };
    Promise.prototype.catch = function (onRejected) {
      return this.then(undefined, onRejected);
    };
  </script>