自定义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 });