美文网首页
自己实现一个Promise

自己实现一个Promise

作者: Eileen_1d88 | 来源:发表于2019-10-16 10:23 被阅读0次

    一、先实现一个只能处理同步任务的promise

    var noop = function(){};
    function PromiseA(fn) {
      this._state = 0;
      this._value = null;
      doResolve(this, fn);
    }
    PromiseA.prototype.then = function(onFulfilled, onRejected) {
      var cb = this._state === 1 ? onFulfilled : onRejected;
      var ret = cb(this._value);
      var promise = new PromiseA(noop);
      promise._state = this._state;
      promise._value = ret;
      return promise;
    };
    function doResolve(promise, fn) {
      fn((res) => {
        _resolve(promise, res);
      }, (error) => {
       _ reject(promise, error);
      })
    }
    
    function _resolve(promise, res) {
      promise._state = 1;
      promise._value = res;
    }
    
    function _reject(promise, res) {
      promise._state = 2;
      promise._value = res;
    }
    

    二、增加异步处理

    var noop = function(){};
    function PromiseA(fn) {
      this._state = 0;
      this._value = null;
      this._deferreds = [];
      doResolve(this, fn);
    }
    PromiseA.prototype.then = function(onFulfilled, onRejected) {
      onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(v) { return v};
      onRejected = typeof onRejected === 'function' ? onRejected : function(r) { return r };
      var promise = new PromiseA(noop);
      // 如果是异步的话,那么执行到这里的时候,this._state还是0
      if (this._state === 0) {
        promise._state = this._state;
        // 将当前的promise和它的回调存在this._deferreds中
        this._deferreds.push({
          promise: promise,
          onFulfilled: onFulfilled,
          onRejected: onRejected
        });
      } else {
        var cb = this._state === 1 ? onFulfilled : onRejected;
        var ret;
        if (cb) {
           ret = cb(this._value);
        }
       this._state === 1 ? _resolve(promise, ret) : _reject(promise, ret);
      }
      return promise;
    };
    function doResolve(promise, fn) {
      try {
        fn((res) => {
          _resolve(promise, res);
        }, (error) => {
          _reject(promise, error);
        })
      } catch(e) {
        _reject(promise, e);
      }
    
    }
    
    function _resolve(promise, newValue) {
      // 如果promise已经执行过,即_state = 1,则什么都不做
      if (promise._state === 1) return;
      // 如果this._deferreds中有未处理的异步回调,则依次执行
      if (promise._deferreds.length !== 0) {
        promise._deferreds.forEach((deferred) => {
          var ret = deferred.onFulfilled(res);
          _resolve(deferred.promise, ret);
        });
        promise._deferreds = [];
        return;
      }
      promise._state = 1;
      promise._value = newValue;
    }
    
    function _reject(promise, newValue) {
      if (promise._state === 2) return;
      if (promise._deferreds.length !== 0) {
        promise._deferreds.forEach((deferred) => {
          var ret = deferred.onRejected(res);
          _reject(deferred.promise, ret);
        });
        promise._deferreds = [];
        return;
      }
      promise._state = 2;
      promise._value = newValue;
    }
    

    三、返回的是一个promise

    var noop = function(){};
    function PromiseA(fn) {
      this._state = 0;
      this._value = null;
      this._deferreds = [];
      doResolve(this, fn);
    }
    PromiseA.prototype.then = function(onFulfilled, onRejected) {
      onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(v) { return v};
      onRejected = typeof onRejected === 'function' ? onRejected : function(r) { return r };
      var promise = new PromiseA(noop);
      // 如果是异步的话,那么执行到这里的时候,this._state还是0
      if (this._state === 0) {
        promise._state = this._state;
        // 将当前的promise和它的回调存在this._deferreds中
        this._deferreds.push({
          promise: promise,
          onFulfilled: onFulfilled,
          onRejected: onRejected
        });
      } else {
        var cb = this._state === 1 ? onFulfilled : onRejected;
        var ret;
        if (cb) {
          ret = cb(this._value);
        }
        this._state === 1 ? _resolve(promise, ret) : _reject(promise, ret)
      }
      return promise;
    };
    function doResolve(promise, fn) {
      try {
        fn((res) => {
          _resolve(promise, res);
        }, (error) => {
          _reject(promise, error);
        })
      } catch(e) {
        _reject(promise, e);
      }
    
    }
    
    function _resolve(promise, newValue) {
      // 如果promise已经执行过,即_state = 1,则什么都不做
      if (promise._state === 1) return;
      // 如果返回值就是Promise, 则调用他很方法,取到新的返回值
      if (newValue instanceof PromiseA) {
        // 需要把新的返回值赋到之前的.then返回的promise上
        newValue.then((res) => {
          _resolve(promise, res);
        }, (reason) => {
          _reject(promise, reason)
        });
        return;
      }
      // promise._deferreds中有未处理的异步回调,则依次执行
      if (promise._deferreds.length !== 0) {
        promise._deferreds.forEach((deferred) => {
          var ret = deferred.onFulfilled(newValue);
          _resolve(deferred.promise, ret);
        });
        promise._deferreds = [];
        return;
      }
      promise._state = 1;
      promise._value = newValue;
    }
    
    function _reject(promise, newValue) {
      if (promise._state === 2) return;
    
      // start ----------------------------------------------------------------------
      if (newValue instanceof PromiseA) {
        newValue.then((res) => {
          _resolve(promise, res);
        }, (reason) => {
          _reject(promise, reason)
        });
        return;
      }
      // end ----------------------------------------------------------------------
    
      if (promise._deferreds.length !== 0) {
        promise._deferreds.forEach((deferred) => {
          var ret = deferred.onRejected(newValue);
          _reject(deferred.promise, ret);
        });
        promise._deferreds = [];
        return;
      }
      promise._state = 2;
      promise._value = newValue;
    }
    

    至此,promise的功能基本有了, 因为一些细节的问题,跟真正的promise会有一些出入,之后慢慢完善。

    相关文章

      网友评论

          本文标题:自己实现一个Promise

          本文链接:https://www.haomeiwen.com/subject/tvadmctx.html