首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

模拟jQuery.Deferred实现

2013-12-22 
模拟jQuery.Deferred实现!var _Deferredfunction(){var callbacks[],firedvar method{done:function(f

模拟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(此方法可用于许多其他场景)

热点排行