在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