Deferred對(duì)象
- 什么是Deferred對(duì)象?
- Deferred對(duì)象是從jQuery 1.5.0版本開始引入的一個(gè)新功能流酬,只要為了解決某些JavaScript代碼需要耗時(shí)很長的問題而開發(fā)的對(duì)象币厕。簡單來說Deferred對(duì)象是為了解決jquery回調(diào)函數(shù)的問題。
- Deferred對(duì)象的含義就是"延遲"到未來某個(gè)點(diǎn)再執(zhí)行康吵。
Deferred對(duì)象的狀態(tài)
deferred對(duì)象有三種狀態(tài)
- 未完成劈榨,會(huì)調(diào)用progress()方法,該方法需要在1.7.0以上才會(huì)有
- 已完成晦嵌,會(huì)調(diào)用done()方法
- 已失敗,會(huì)調(diào)用fail()方法
Deferred對(duì)象功能
- 實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用
- 為同一操作綁定多個(gè)回調(diào)函數(shù)
- 為多個(gè)操作指定同一回調(diào)函數(shù)
- 為普通操作提供回調(diào)函數(shù)接口
1. $.ajax(obj)的鏈?zhǔn)綄懛?/h6>
在jquery1.5.0
以前拷姿,調(diào)用 $.ajax()
方法返回的是 XMLHttpRequest
對(duì)象惭载,這就無法進(jìn)行鏈?zhǔn)讲僮鳌?/p>
如果在 jquery1.5.0
以后,調(diào)用 $.ajax()
方法返回的是 deferred
對(duì)象响巢,這就可以進(jìn)行鏈?zhǔn)讲僮髁恕?/p>
// jquery1.5.0 及以前
var xhr = $.ajax({
url: "test.html",
success: function(){
alert("哈哈描滔,成功了!");
},
error:function(){
alert("出錯(cuò)啦踪古!");
}
});
// jquery1.5.0之后
$.ajax("/echo/html/")
.done(function(){ alert("哈哈含长,成功了券腔!"); })
.fail(function(){ alert("出錯(cuò)啦!"); });
2. 指定同一操作的多個(gè)回調(diào)函數(shù)
deferred對(duì)象的一大好處拘泞,就是它允許你自由添加多個(gè)回調(diào)函數(shù)纷纫,直接把它加在后面就行了。
$.ajax("/echo/html/")
.done(function(){ alert("哈哈陪腌,成功了辱魁!");} )
.fail(function(){ alert("出錯(cuò)啦!"); } )
.done(function(){ alert("第二個(gè)回調(diào)函數(shù)诗鸭!");} );
// 彈出 哈哈染簇,成功了!
// 彈出 第二個(gè)回調(diào)函數(shù)强岸!
3. 為多個(gè)操作指定同一回調(diào)函數(shù)
下面代碼的意思是锻弓,先執(zhí)行兩個(gè)操作 $.ajax("test1.html")
和 $.ajax("test2.html")
,如果都成功了蝌箍,就運(yùn)行done()指定的回調(diào)函數(shù)青灼;如果有一個(gè)失敗或都失敗了,就執(zhí)行fail()指定的回調(diào)函數(shù)十绑。
$.when($.ajax("test1.html"), $.ajax("test2.html"))
.done(function(){ alert("哈哈聚至,成功了!"); })
.fail(function(){ alert("出錯(cuò)啦本橙!"); });
4. 為普通操作提供回調(diào)函數(shù)接口
var wait = function(){
var tasks = function(){
alert("執(zhí)行完畢扳躬!");
};
setTimeout(tasks,5000);
};
$.when(wait())
.done(function(){ alert("哈哈,成功了甚亭!"); })
.fail(function(){ alert("出錯(cuò)啦贷币!"); });
// 因?yàn)橛泻臅r(shí)操作,tasks函數(shù)還沒有執(zhí)行完成亏狰,done里面的函數(shù)就已經(jīng)執(zhí)行了役纹,出現(xiàn)的結(jié)果就是
// 哈哈,成功了暇唾!
// 執(zhí)行完畢促脉!
// 這樣就違背了回調(diào)函數(shù)的本意
// 起不到回調(diào)函數(shù)的作用的原因在于$.when()的參數(shù)只能是deferred對(duì)象,所以我們需要提供一個(gè)deferred對(duì)象作為參數(shù)
// 改進(jìn)
var dtd = $.Deferred(); // 新建一個(gè)deferred對(duì)象
var wait = function(dtd){
var tasks = function(){
alert("執(zhí)行完畢策州!");
dtd.resolve(); // 將dtd對(duì)象的執(zhí)行狀態(tài)從"未完成"改為"已完成"瘸味,從而觸發(fā)done()方法
};
setTimeout(tasks,5000);
return dtd;
};
$.when(wait(dtd)) // 現(xiàn)在,wait(dtd)函數(shù)返回的是deferred對(duì)象了
.done(function(){ alert("哈哈够挂,成功了旁仿!"); })
.fail(function(){ alert("出錯(cuò)啦!"); });
Deferred對(duì)象的方法
$.Deferred()
生成一個(gè)deferred對(duì)象deferred.done()
指定操作成功時(shí)的回調(diào)函數(shù)deferred.fail()
指定操作失敗時(shí)的回調(diào)函數(shù)deferred.promise()
沒有參數(shù)時(shí)孽糖,返回一個(gè)新的deferred對(duì)象枯冈,該對(duì)象的運(yùn)行狀態(tài)無法被改變毅贮;接受參數(shù)時(shí),作用為在參數(shù)對(duì)象上部署deferred接口deferred.resolve(arg)
手動(dòng)改變deferred對(duì)象的運(yùn)行狀態(tài)為"已完成"尘奏,從而立即觸發(fā)done()方法deferred.reject(arg)
這個(gè)方法與deferred.resolve()正好相反滩褥,調(diào)用后將deferred對(duì)象的運(yùn)行狀態(tài)變?yōu)?已失敗",從而立即觸發(fā)fail()方法$.when()
為多個(gè)操作指定回調(diào)函數(shù)-
deferred.then()
有時(shí)為了省事罪既,可以把done()和fail()合在一起寫铸题,這就是then()方法,如下代碼$.when($.ajax('/data.php')).then(succeedFunc, failedFunc); /* 注意:如果then()有兩個(gè)參數(shù)琢感,那么第一個(gè)參數(shù)是done()方法的回調(diào)函數(shù)丢间,第二個(gè)參數(shù)是fail()方法的回調(diào)方法。如果then()只有一個(gè)參數(shù)驹针,那么等同于done() */
-
deferred.always()
這個(gè)方法也是用來指定回調(diào)函數(shù)的烘挫,它的作用是,不管調(diào)用的是deferred.resolve()還是deferred.reject()柬甥,最后總是執(zhí)行$.ajax().always(function exec () { console.log('exec函數(shù)無論如何都會(huì)被執(zhí)行')饮六; });