jquery deferred对象
jquery deferred对象一、jquery源码中Deferred的定义
jQuery.extend({
Deferred: function( func ) {
var tuples = [
// action, add listener, listener list, final state
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
[ "notify", "progress", jQuery.Callbacks("memory") ]
],
...
// All done!
return deferred;
},
// Deferred helper
when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
resolveValues = core_slice.call( arguments ),
length = resolveValues.length,
....
return deferred.promise();
}
});
二、Deferred定义的说明
1、$.Deferred的实现
(1)、创建三个$.Callbacks对象,分别表示成功,失败,处理中三种状态
(2)、创建了一个promise对象,具有state、always、then、primise方法
(3)、通过扩展primise对象生成最终的Deferred对象,返回该对象
2、$.when的实现
(1)、接受若干个对象,参数仅一个且非Deferred对象将立即执行回调函数
(2)、Deferred对象和非Deferred对象混杂时,对于非Deferred对象remaining减1
(3)、Deferred对象总数 = 内部构建的Deferred对象 + 所传参数中包含的Deferred对象
(4)、所传参数中所有Deferred对象每当resolve时remaining减1,直到为0时(所有都resolve)执行回调
三、Deferred对象常用的方法
1、构造函数
- var deferred = $.Deferred();
2、deferred.resolve()
(1)、手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。
(2)、有段程序,如果我不想马上执行,而是想在这里注册一下,在将来的某个时候让他执行,则可以使用这个方法
var deferred = $.Deferred();
deferred.done(function () {
$.get(
"content.txt",
function (resp) {
alert(resp);
});
});
alert("other things...")
setTimeout(function() {
deferred.resolve()
}, 3000)
(3)、代码说明
先将要执行的代码写上,然后去做其他的事情,等到我想要这段代码执行的时候,只要调用 deferred.resolve();就可以了。
3、deferred.reject()
(1)、这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法。
(2)、reject函数可以接收一个参数,用于传给deferred的failCallback。
$(function(){
var dfd = $.Deferred();
var func1 = function() {alert("1");};
var func2 = function() {alert("2");};
dfd.fail(func1, [func1, func2], func2);
//调用reject方法触发fail事件处理函数
dfd.reject();
})
4、deferred.then()
(1)、用于将done()和fail()合在一起写
(2)、用于给一个deferred对象添加监听器。
deferred.then( doneCallbacks, failCallbacks )
参数说明
doneCallbacks: 一个函数,或者是一组函数,在deferred.resolve时调用
failCallbacks: 一个函数,或者是一组函数,在deferred.reject时调用
$.get("testURL").then(
function(){ alert("$.get succeeded"); },
function(){ alert("$.get failed!"); }
);
5、deferred.done()
(1)、操作成功时的回调函数
(1)、在Deferred对象被resolve时执行
(2)、可以附加多个回调函数
function doneFunc1() {
alert("doneFunc1");
}
function doneFunc2() {
alert("doneFunc2");
}
deferred.resolve();
6、deferred.fail()
(1)、操作失败时的回调函数,与.done 相反
(2)、 在Deferred对象被reject时执行
var deferred = $.Deferred();
deferred.fail(function () {
alert("fail!");
});
deferred.reject();
7、deferred.always()
这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
var deferred = $.Deferred()
deferred.always(function() {
var state = deferred.state()
if ( state === 'resolved') {
alert('success')
} else if (state === 'rejected') {
alert('fail')
}
})
setTimeout(function() {
deferred.resolve()
//deferred.reject()
}, 3000)
8、deferred.notify()
(1)、deferred.resolve和deferred.reject都属于终结性的行为,也就是说,调用了deferred.resolve和deferred.reject后,再也不能对deferred对象进行状态上的改变(resolve, reject, notify, resolveWith, rejectWith, 和 notifyWith)。
(2)、如果我们想让deferred对象做一些事情,而又不想终结该deferred对象,该怎么办哪?这就是deferred.notify方法的作用。
(3)、和deferred.progress配对使用
var deferred = $.Deferred();
deferred.progress(function (args) {
alert(args);
});
deferred.notify("notify1");
deferred.notify("notify2");
deferred.resolve();
四、$.deferred与$.when()一起调用
1、$.when()提供了一种根据Defererred对象的状态来执行回调函数的办法。它接受一个或者多个Defeered对象。
$(function(){
$.when($.ajax('test.html')).then(function(data, textStatus, jqXHR){
console.log(data);
},function(){
alert('failure');
})
});
2、在只使用一个参数的情况下,$.when()和直接使用Deferred对象没有什么区别,它也返回一个Deferred对象。
3、$.when()更大的作用在于使用多个Defeered对象时,此时$.when()返回一个包含所有Deferred状态的超级Deferred对象。并且如果有一个Deferred失败,那么这个超级Deferred的状态将为failed,只有在所有Deferred对象都实现时,返回的超级Deferred对象状态才为resolved。
$(function(){
//假设test.html不存在,那么将调用fail回调函数,弹出alert对话框
$.when($.ajax('test.html'), $.ajax('test.html')).then(function(args1,args2){
console.log(args1);
},function(){
alert('failure');
})
});
4、非常适用于 当一个回调函数需要依赖多个ajax请求取回数据才能被触发的情况。
五、与ajax等回调函数的关系
1、jQuery书写ajax的风格可以这样写
$.ajax(url)
.done(success)
.fail(fail)
2、Deferred可以添加多个回调
$.ajax(url)
.done(success1)
.done(success2)
.fail(fail2)
.fail(fail2)
3、如果多个请求完成后才算成功,则可以用$.when
var ajax1 = $.ajax(url1)
var ajax2 = $.ajax(url2)
$.when(ajax1, ajax2).done(success)
标签: