function promise(fn){
var P = 1,
F = 2,
R = 3;
var state = P,
value = null,handles = [];
function fulFilled(res){
state = F;
value = res;
handles.forEach(handle);
handles = null;
}
function rejected(res){
state = R;
value = res;
handles.forEach(handle);
handles = null;
}
function handle(handler){
if(state === P){
handles.push(handler)
}else{
if(state === F&&typeof handler.onFulfilled === 'function'){
handler.onFulfilled(value);
}
if(state === R&&typeof handler.onRejected === 'function'){
handler.onRejected(value);
}
}
}
function resolve(res){
try{
var then = getThen(res);
if(then){
doResolve(then.bind(res),resolve,rejected)
return;
}
fulFilled(res)
}catch (e){
rejected(e);
}
}
function getThen(value){
var type = typeof value;
if(type === 'object'||type === 'function'){
if(typeof value.then === 'function')
return value.then
}
return null
}
function doResolve(fn,fulFilled,rejected){
var done = false
try{
fn(function(res){
if(done)return;
done = true;
fulFilled(res);
},function(){
if(done)return;
done = true;
rejected(res)
})
}catch (e){
if(done)return;
done = true;
rejected(e)
}
}
this.done = function(onFulfilled,onRejected){
setTimeout(handle({
onFulfilled,
onRejected
}
))
}
this.then = function(onFulfilled,onRejected){
var self = this;
return new promise(function(resolve,rejected){
return self.done(function(res){
if(typeof onFulfilled === 'function'){
try{
return resolve(onFulfilled(res))
}catch(e){
return rejected(e)
}
}else{
return resolve(res)
}
},function(res){
if(typeof onRejected === 'function'){
try{
return resolve(onRejected(res))
}catch(e){
return rejected(e)
}
}else{
return rejected(res)
}
})
})
}
doResolve(fn,resolve,rejected);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.