模拟jQuery.Deferred实现!


var _Deferred=function(){
var callbacks=[],fired;
var method={
done:function(func){
callbacks.push(func);
if(fired){
method.resolveWith(fired[0],fired[1]);
}
return this
},
resolveWith:function(context,args){
args=args || [];
fired=[context,args];
while(callbacks[0]){
callbacks.shift().apply(context,args);
}
return this;
},
resolve:function(){
method.resolveWith(this,arguments);
return this;
}
}
return method;
}

var Deferred=function(){
var doneDeferred=_Deferred(),failDeferred=_Deferred();
$.extend(doneDeferred,{
reject:failDeferred.resolve,
rejectWidth:failDeferred.resolveWith,
fail:failDeferred.done,
always:function(func){
doneDeferred.done(func).fail(func);
},
promise:function(){
return {
done:doneDeferred.done,
fail:doneDeferred.fail,
always:doneDeferred.always,
promise:doneDeferred.promise
};
}
});
return doneDeferred;
}

var when=function(deferredItem){
var args=arguments,length=arguments.length,count=length;
var deferred=(length<=1&&deferredItem&&deferredItem.promise)?deferredItem:Deferred();
if(deferred!=deferredItem){
var doneBack=function(i){
return function(value){
args[i]=arguments.length>1?[].slice.call(arguments,0):value;
if(!(--count)){
deferred.resolveWith(deferred,args);
}
}
}
for(var i=0;i<arguments.length;i++){
if(arguments[i] && arguments[i].promise){
arguments[i].done(doneBack(i)).fail(deferred.reject);
}else{
count--;
}
}
if(!count){
deferred.resolveWith(deferred,args);
}
}
return deferred.promise();
}

//测试
function wait(){
var df=Deferred();
setTimeout(function(){
alert('end wait..');
df.reject();
},2000);
return df.promise();
}
function wait2(){
var df=Deferred();
setTimeout(function(){
df.resolve();
},4000);
return df.promise();
}
function f1(){
alert('ttt');
}
when(wait(),wait2()).done(function(){
f1();
});


延迟对象jQuery.Deferred()设计思想:
1)函数队列,done与fail各维护一个!(抽离出来封装一个闭包)
3)done/fail的时候把新的函数放进对应的函数队列
3)resolve的时候循环shift并调用done函数队列;reject的时候循环shift并调用fail函数队列
4)利用标志变量fired存储resolve或reject的上下文和参数,可用于判断deferred是否已resolve或reject,以及传递上下文和参数!(这样一来,done/fail方法在resolve/reject后面执行也不怕了)
5)when方法:判断是否所有deferred已resolve的时候,很巧妙地利用了count记数法,resolve一个count减去1(此方法可用于许多其他场景)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值