Skip to content

Instantly share code, notes, and snippets.

@calvinmetcalf
Last active December 26, 2015 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calvinmetcalf/7196496 to your computer and use it in GitHub Desktop.
Save calvinmetcalf/7196496 to your computer and use it in GitHub Desktop.
'use strict';
var immediate = require('immediate');
function Promise(resolver) {
if (!(this instanceof Promise)) {
return new Promise(resolver);
}
var successQueue = [];
var failureQueue = [];
var resolved = false;
this.then = function(onFulfilled, onRejected) {
if(resolved){
return resolved(onFulfilled, onRejected);
} else {
return pending(onFulfilled, onRejected);
}
};
function pending(onFulfilled, onRejected){
return new Promise(function(success,failure){
if(typeof onFulfilled === 'function'){
successQueue.push({
resolve: success,
reject: failure,
callback:onFulfilled
});
}else{
successQueue.push({
next: success,
callback:false
});
}
if(typeof onRejected === 'function'){
failureQueue.push({
resolve: success,
reject: failure,
callback:onRejected
});
}else{
failureQueue.push({
next: failure,
callback:false
});
}
});
}
var scope = this;
function resolve(success, value){
if(resolved){
return;
}
resolved = createResolved(scope, value, success?0:1);
var queue = success ? successQueue : failureQueue;
var len = queue.length;
var i = -1;
while(++i < len) {
if (queue[i].callback) {
immediate(execute,queue[i].callback, value, queue[i].resolve, queue[i].reject);
}else if(queue[i].next){
queue[i].next(value);
}
}
}
function reject(reason){
resolve(false,reason);
}
function fulfill(value){
resolve(true,value);
}
function fulfillUnwrap(value){
unwrap(fulfill, reject, value);
}
try{
resolver(fulfillUnwrap,reject);
}catch(e){
reject(e);
}
}
function unwrap(fulfill, reject, value){
if(value && typeof value.then==='function'){
value.then(fulfill,reject);
}else{
fulfill(value);
}
}
function createResolved(scope, value, whichArg) {
function resolved() {
var callback = arguments[whichArg];
if (typeof callback !== 'function') {
return scope;
}else{
return new Promise(function(resolve,reject){
immediate(execute,callback,value,resolve,reject);
});
}
}
return resolved;
}
function execute(callback, value, resolve, reject) {
try {
unwrap(resolve,reject,callback(value));
} catch (error) {
reject(error);
}
}
module.exports = Promise;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment