我的認爲阮一峯老師講的關於deferred對象是最容易理解的。javascript
deferred對象是jquery的回調函數解決方案。解決了如何處理耗時操做的問題,對那些操做提供了更好的控制,以及統一的編程接口。html
deferred對象的功能:java
1.將ajax操做改成鏈式jquery
對於$.ajax()操做完成以後,若是使用的是低於1.5版本的jquery,返回的是XHR對象,高於1.5版本返回的是deferred對象。deferred對象可進行鏈式操做。ajax
$.ajax({ url:"test.html", success:function(){},//success方法指定操做成功後的回調函數 error:function(){}//error方法指定操做失敗後的回調函數 }) //新的寫法 $.ajax("test.html") .done(function(){})//done()至關於success方法 .failed(function(){})//failed()至關於error方法
2.指定同一操做的多個回調函數編程
deferred對象容許自由添加多個回調函數,回調函數按添加順序執行api
$.ajax("test.html") .done(function(){}) .failed(function(){}) .dene(function(){})//直接將多個方法加在後面
3.爲多個操做指定回調函數promise
deferred對象容許爲多個事件指定一個回調函數,利用$.when()方法函數
//先執行兩個操做$.ajax("test1.html")和$.ajax("test2.html"),若是都成功了,就運行done()指定的回調函數;若是有一個失敗或都失敗了,就執行fail()指定的回調函數 $.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){}) .fail(function(){});
4.普通操做的回調函數接口url
deferred對象將回調函數的接口從ajax操做擴展到了全部操做。$.when()的參數只能是deferred對象
var wait = function(){ alertvar tasks = function(){ alert("執行完畢!"); }; setTimeout(tasks,5000); };
爲wai函數添加回調函數
var dtd = $.Deferred(); // 新建一個Deferred對象 var wait = function(dtd){ var tasks = function(){ alert("執行完畢!"); dtd.reject(); // 改變Deferred對象的執行狀態 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出錯啦!"); });
存在問題:dtd是全局變量,容易被修改,解決辦法:jquery的deferred.promise()方法。在原來的deferred對象上返回另外一個deferred對象,後者只開放與改變執行狀態無關的方法(好比done()方法和fail()方法),屏蔽與改變執行狀態有關的方法(好比resolve()方法和reject()方法),從而使得執行狀態不能被改變。
第一種方法:
var dtd = $.Deferred(); // 新建一個Deferred對象 var wait = function(dtd){ var tasks = function(){ alert("執行完畢!"); dtd.resolve(); // 改變Deferred對象的執行狀態 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise對象
};
var d = wait(dtd); // 新建一個d對象,改成對這個對象進行操做 $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出錯啦!"); }); d.resolve(); // 此時,這個語句是無效的
第二種方法
var wait = function(dtd){ var dtd = $.Deferred(); //在函數內部,新建一個Deferred對象 var tasks = function(){ alert("執行完畢!"); dtd.resolve(); // 改變Deferred對象的執行狀態 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise對象 }; $.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出錯啦!"); });
第三種方法:使用deferred對象的構造函數$.Deferred()
$.Deferred(wait) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出錯啦!"); }); //jQuery規定,$.Deferred()能夠接受一個函數名(注意,是函數名)做爲參數,$.Deferred()所生成的deferred對象將做爲這個函數的默認參數。
第四種方法:在wait方法上直接部署deferred對象
var dtd = $.Deferred(); // 生成Deferred對象 var wait = function(dtd){ var tasks = function(){ alert("執行完畢!"); dtd.resolve(); // 改變Deferred對象的執行狀態 }; setTimeout(tasks,5000); }; dtd.promise(wait); wait.done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出錯啦!"); }); wait(dtd);
困了,今天先到這裏,明天早上繼續~