Skip to content

Instantly share code, notes, and snippets.

@joeylin
Last active December 28, 2015 13:38
Show Gist options
  • Save joeylin/7508665 to your computer and use it in GitHub Desktop.
Save joeylin/7508665 to your computer and use it in GitHub Desktop.
Create your own promise
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment