您好,登錄后才能下訂單哦!
1、deferred的英文意思是:延期的
2、deferred的思想:當遇到處理耗時很多的js數據請求時,同步或者異步的操作都可能會碰到,客戶端不能一直等待下去,這時候我們的處理思路是給該請求注冊一個回調事件,等服務器有結果返回時執行。總之,deferred就是回調方法的解決方案。
3、故事背景:
當去超市定購一臺家電,因為超市暫時沒貨需要從別的倉庫調貨(這時就產生了一個deferred),貨到后就會立即給配送,但是需要一個約定(promise)即購物單上需標明貨物型號、產品外觀、價格等等參數,如果在周轉貨物的過程中如果有什么意外(如周轉時間太長)就應該通知客戶(notify,這個通知可能是多次的,因為異步狀態有多個狀態的變化)。如果等到約定發貨的時候如果發現和購物單上的一致,我們就認為這個promise有效,要收貨簽字(resolve),如果不一致就要拒簽(reject)。
4、jquery中的deferred
該對象的引入是在jquery的1.5版本(),是通過使用jquery.Deferred()方法創建個可以鏈式調用的工具對象,可以注冊多個回調方法到回調隊列。
(1)1.5版本前經常使用的ajax形式,返回的是XHR對象,該版本后返回的是deferred對象:
$.ajax({ url: "test.html", success: function(){ alert("success"); }, error:function(){ alert("error"); } });
1.5版本后仍然支持上面的寫法,但是1.5后可以鏈式操作,如下:
$.ajax({ url: '/path/to/file', type: '', dataType: '', data: {}, }) .done(function() { console.log("success"); }) .fail(function() { console.log("error"); })
并且還可以繼續添加鏈接方法,如下形式:
$.ajax({ url: '/path/to/file', type: '', dataType: '', data: {}, }) .done(function() { console.log("first done"); }) .fail(function() { }) .done(function(){ console.log("second done"); });
這時候如果我想等到兩個ajax請求都返回后再去執行done、fail方法該怎么辦呢?
很簡單,你可以使用:
$.when($.ajax("test1.html"), $.ajax("test2.html"))
.done(function(){
alert("兩個請求都成功了!");
});
注:when接受的是deferred對象
when的實現原理可以參考jquery(1.11.1)源碼中的3340行到3389行
(2)到現在咱們還沒有提到resolve,reject和notify,別急,馬上就開始,
要說清楚這個問題,就要引入一個新概念"執行狀態"。
jQuery規定,deferred對象有三種執行狀態----未完成,已完成和已失敗。
如果執行狀態是"已完成"(resolved),將deferred對象的執行狀態從"未完成"改為"已完 成", deferred對象立刻調用done()方法指定的回調函數,
如果執行狀態是"已失敗",調用fail()方法指定的回調函數,
如果執行狀態是"未完成",則會觸發nodify方法指定的回調函數
例子如下:
http://jsfiddle.net/houyaowei/0jzL93j2/ 該例子立即執行done方法
http://jsfiddle.net/houyaowei/khgoqnp1/3/ reject
http://jsfiddle.net/houyaowei/ummefcLw/5/ resolve
http://jsfiddle.net/houyaowei/rcocx47a/ 動態改變resolve
為了處理運行狀態被動態改變的問題,jQuery提供了deferred.promise()方法。它的作用是, 在原來的deferred對象上返回另一個新deferred對象(promise),
該對象的運行狀態無法被改變
promise只開放與改變執行狀態無關的方法(比如done()方法和fail()方法),
屏蔽與改變執行狀態有關的方法(比如resolve()方法和reject()方法)
例子如下:
http://jsfiddle.net/houyaowei/b4h7we8t/2/ promise
(3)promise的then方法:
為了處理方便,done和fail方法合并為then方法,
deferred.then( doneFilter [, failFilter ] [, progressFilter ] )
doneFilter: 為done的處理方法
可選參數failFilter為原fail的處理方法
例如:
$.get( "index.html" ).then( function() { alert( " succeeded" ); }, function() { alert( " failed!" ); } );
詳細的API請訪問 http://api.jquery.com/
歡迎拍磚,如果哪個地方描述的不合理或者講的有錯,請留言,謝謝!!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。