美文网首页
实现一个简单的Promise/Deferred框架

实现一个简单的Promise/Deferred框架

作者: Aaaaaaaaaaayou | 来源:发表于2016-10-10 16:18 被阅读145次

    利用nodejs的event模块,可以实现一个最简单的Promise/Deferred框架:

    Promise

    // Promise 继承自EventEmitter
    var Promise = function () {
      EventEmitter.call(this);
    };
    util.inherits(Promise,EventEmitter);
    
    // then方法,绑定成功、失败、进度事件
    Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
      if (typeof fulfilledHandler === 'function') {
        this.once('success',fulfilledHandler)
      }
      if (typeof errorHandler === 'function') {
        this.once('error', errorHandler);
      }
      return this;
    };
    

    Deferred

    var Deferred = function () {
      this.state = 'unfulfilled';
      this.promise = new Promise();
    };
    // 触发成功事件
    Deferred.prototype.resolve = function (obj) {
      this.state = 'fulfilled';
      this.promise.emit('success',obj);
    };
    // 触发失败事件
    Deferred.prototype.reject = function (err) {
      this.state = 'failed';
      this.promise.emit('error',err);
    };
    

    使用方法

    function test() {
      var defer = new Deferred();
      setTimeout(function(){
          defer.resolve('test')
      },0);
      return defer.promise;
    }
    
    test()
      .then(function(msg){
        console.log(msg); // test
      })
    
    

    实现链式调用

    • Promise
    var Promise = function () {
      EventEmitter.call(this);
      // 队列用于存储待执行的回调函数
      this.queue = [];
      this.isPromise = true;
    };
    util.inherits(Promise,EventEmitter);
    
    Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
      var handler = {};
      if (typeof fulfilledHandler === 'function') {
        handler.fulfilled = fulfilledHandler;
      }
      if (typeof errorHandler === 'function') {
        handler.error = errorHandler;
      }
      // 将then中传入的函数都添加到promise的队列中
      this.queue.push(handler);
      // then函数返回自身
      return this;
    };
    
    • Deferred
    var Deferred = function () {
      this.state = 'unfulfilled';
      this.promise = new Promise();
    };
    
    Deferred.prototype.resolve = function (obj) {
      var promise = this.promise;
      var handler;
      while ((handler = promise.queue.shift())) {
        if (handler && handler.fulfilled) {
          // 正常情况下,fulfilled函数会继续返回一个promise
          var ret = handler.fulfilled(obj);
          if (ret && ret.isPromise) {
            // 将当前Defferred对象的promise引用改为新的Promise对象,将队列中余下的回调转交给它
            ret.queue = promise.queue;
            this.promise = ret;
            return;
          }
        }
      }
    };
    
    Deferred.prototype.reject = function (err) {
      var promise = this.promise;
      var handler;
      while ((handler = promise.queue.shift())) {
        if (handler && handler.error) {
          var ret = handler.error(err);
          if (ret && ret.isPromise) {
            ret.queue = promise.queue;
            this.promise = ret;
            return;
          }
        }
      }
    };
    
    • 使用
    function test() {
      var defer = new Deferred();
      setTimeout(function(){
          defer.resolve('test1')
      },0);
      return defer.promise;
    }
    
    test()
      .then(function(msg){
        console.log(msg);
        var defer = new Deferred();
        setTimeout(function(){
                defer.resolve('test2')
        })
          return defer.promise;
      })
      .then(function(msg){
        console.log(msg)
      })
    

    欢迎光临我的博客:http://www.paradeto.com

    相关文章

      网友评论

          本文标题:实现一个简单的Promise/Deferred框架

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