自定义promise的实现

/* Promise */
function Promise() {
  this.queues = [];
  this.fails = [];
  this.progress = [];
  this.nextVal = null;
  this.nextErr = null;
}

Promise.prototype.then = function ( onFulfilled, onRejected, progress) {
  this.done.call(this, onFulfilled);
  if (Object.prototype.toString.call(onRejected) == "[object Function]") {
    this.fail.call(this, onRejected);
  }
  if (Object.prototype.toString.call(progress) == "[object Function]") {
    this.progress.call(this, progress);
  }
  return this;
};

Promise.prototype.done = function (func) {
  this.queues.push(function(data) {
    this.nextVal = func.call(null, data);
  });
  return this;

};

Promise.prototype.fail = function (func) {
  this.fails.push( function(err) {
    this.nextErr = func.call(null, err);
  });
};

/*  Deferred */
function Deferred() {
  this.status = 'pending';
  this.promise = new Promise();
}

Deferred.prototype.resolve = function ( data) {
  if (this.status == 'pending') {
    this.promise.queues.forEach(function(func, i) {
      func.call(this, this.nextVal || data);
    }, this.promise);

    this.status = 'fulfilled';
  }
};

Deferred.prototype.reject = function(err) {
  if (this.status == 'pending') {
    this.promise.fails.forEach(function(func, i) {
      func.call(this, this.nextErr || err);
    }, this.promise);
    this.status = 'rejected';

  }
};


Deferred.when = function () {
  var promises = Array.prototype.slice.call(arguments, 0), results = [], start = 0, total = promises.length, defer = new Deferred();

  if (total === 0) return defer.resolve(results);
  function notifier(index) {
    return function(data) {
      start += 1;
      results[index] = data === undefined ? null : data;
      if (start == total) {
          defer.resolve(results);
      }
    }'
  }

  for (var i = 0; i < total; i++) {
    // promise.done(function(data) { TODO }}
    promises[i].done(notifier(i));
  }

  return defer.promise;
};

Deferred.queues = function(funcs) {
  var defer = new Deferred();
  (function chain(data) {
    if (funcs.length === 0) 
       defer.resolve(data);
    else 
       funcs[0].call(null, data).done(function(d) {
          funcs.splice(0, 1);
          chain.call(null, d);
       });
  })();

  reurn defer.promise;
};







 example

var defer = new Deferred();

defer.resolve('1111');

defer.reject(000);

defer.promise;

 

Deferred.when(defer.promise, defer.promise).done(function(d) { //DODO });

Deferred.queues([p1, p2, p3]).done(function(d) { //DODO });

posted @ 2015-02-16 16:47  风之约  阅读(759)  评论(0编辑  收藏  举报