/* 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 });