在jq1.50版本以上新增了deferred对象,可使我们做函数回掉时更加的方便快捷,也让代码的可读性大大增加,具体操作方法类似jq经典的链式操作方法.
假设我们有一个done.php的接口,
<?php echo 'done!' ?>
我们可以通过下面这种利用延迟对象的方法去
$.ajax({url:'d1eferred.php'}) .done(function(data){ console.log(data)//done! }) .fail(function(){ alert('failed') })
done()相当于success方法,fail()相当于error方法。采用链式写法以后,代码的可读性大大提高。
我们还可以
$.ajax({url:'d1eferred.php'}) .done(function(data){ console.log(data) }) .fail(function(){ alert('failed'); }) .done(function(){ alert('第二个回调'); })
会我们的操作指定多个回调函数。
还可以这样
$.when($.ajax('1.php'),$.ajax('2.php')) .done(function(data){ console.log(data) }) .fail(function(){ alert('failed'); }) .done(function(){ alert('第二个回调'); })
为两个执行后的方法指定同样的回调。
假设有一个超时函数
function wait(){ function task(){ alert('wait over'); } setTimeout(function(){ task(); },5000) }
我们这样去给他添加一个done方法;
$.when(wait()) .done(function(){ alert('wait的回调') });
上面的做法并不会在5秒后才调用回调.
我们需要重新改造wait()函数
var dtd = $.Deferred(); function wait(dtd){ function task(){ alert('wait over'); dtd.resolve(); } setTimeout(function(){task()},5000); return dtd; }
$.when(wait(dtd)) .done(function(){ alert('wait的回调') });
5秒后成功调用done回调;
jQuery规定,deferred对象有三种执行状态----未完成,已完成和已失败。如果执行状态是"已完成"(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是"已失败"(reject),调用fail()方法指定的回调函数;如果执行状态是"未完成",则继续等待,或者调用progress()方法指定的回调函数(jQuery1.7版本添加)。
我们上面这样做有一个弊端就是生命的延迟对象都是全局的deferred对象,只要在全局返回内随便的让dtd.resolve();done方法将会立即被调用;
所以更好的方法是让dtd作为局部对象存在
jQuery提供了deferred.promise()方法。它的作用是,在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。
function wait(){ var dtd = $.Deferred(); function task(){ alert('wait over'); dtd.resolve(); } setTimeout(function(){task()},5000); return dtd.promise(); }
我们再次的利用when方法去调用回调
$.when(wait()) .done(function(){ alert('wait的回调'); }) .fail(function(){ alert('fail回调'); })
此文只做为我的学习笔记,具体的内容大都取自
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html