var util = require('util'); var events = require('events'); function Promise(done) { Promise.super_.call(this); this.results = null; this.errors = null; this.ended = false; // Done Callback if ('function' === typeof done) { this.done(done); } } util.inherits(Promise, events.EventEmitter); Promise.prototype.resolve = function() { // Arguments processing var args = slice(arguments); // Done this.emit('resolve', args); this.ended = true; this.results = args; return this; }; Promise.prototype.reject = function() { // Arguments processing var args = slice(arguments); // Error! this.emit('reject', args); this.ended = true; this.errors = args; return this; }; Promise.prototype.then = function(onResolve, onReject) { var promise = new Promise(); var self = this; onResolve = onResolve || noop; onReject = onReject || noop; self .done(function() { var ret = onResolve.apply(self, arguments); if (ret instanceof Promise) { ret.then( function() { promise.resolve.apply(promise, arguments); }, function(err) { promise.reject(err); } ); } else if (ret instanceof Error) { promise.reject(ret); } }) .fail(function(err) { onReject.call(self, err); promise.reject(err); }); return promise; }; Promise.prototype.done = function(callback) { var self = this; if (self.ended) { // Done before if (self.results !== null) { callback.apply(self, self.results); } } else { // Event listening self.on('resolve', function(args) { var ret = callback.apply(self, args); if (ret instanceof Promise) { ret.fail(self.reject.bind(self)); } }); } return self; }; Promise.prototype.fail = function(callback) { var self = this; if (self.ended) { // Reject Before if (self.errors !== null) { callback.apply(self, self.errors); } } else { // Event listening self.on('reject', function(args) { callback.apply(self, args); }); } return self; }; function slice(argv) { var args = []; for (var i = 0; i < argv.length; i++) { args[i] = argv[i]; } return args; } function noop() { return false; }