Last active
December 26, 2015 18:39
-
-
Save calvinmetcalf/7196496 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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