Да, велосипед.
Promise описываемый в
учебнике мне не понравился.
jQ.deferred не реализовывал желаемого (а может просто руки кривые). Хотелось, чтобы обработчик вызывался, даже если Promise.state!=pending.
function Promise(){
var state='pending',
done=[],
fail=[],
always=[],
context,
_arguments=[],
execute=function(list){
var containers=[list,always],
args=[];
for(var container in containers){
if(!containers.hasOwnProperty(container))
continue;
container=containers[container];
for(var i in container){
if(!container.hasOwnProperty(i))
continue;
container[i].apply(context||window,_arguments);
delete container[i];
}
}
};
this.set_arguments=function(_args){
_arguments=[];
for(var i=0;i<_args.length;i++)
_arguments.push(_args[i]);
return this;
};
this.resolve=function(){
state='resolved';
this.set_arguments(arguments);
execute(done);
return this;
};
this.reject=function(){
state='rejected';
this.set_arguments(arguments);
execute(fail);
return this;
};
this.done=function(){
done.push(arguments[0]);
if(state=='resolved')
this.resolve.apply(this,_arguments);
return this;
};
this.fail=function(){
fail.push(arguments[0]);
if(state=='rejected')
this.reject.apply(this,_arguments);
return this;
};
this.always=function(){
always.push(arguments[0]);
if(state!='pending')
this[state=='resolved'?'resolve':'reject']();
return this;
};
this.set_context=function(cont){
context=cont;
return this;
};
function Instance(self){
var __context=self;
this.done=function(callback){
__context.done.call(__context,callback);
return this;
};
this.fail=function(callback){
__context.fail.call(__context,callback);
return this;
};
this.always=function(callback){
__context.always.call(__context,callback);
return this;
};
this.set_context=function(context){
__context.set_context.call(__context,context);
return this;
};
return this;
};
this.promise=function(){
return new Instance(this);
};
return this;
}