前端項目的開發,不僅僅涉及到同步的概念,而且還會經常穿插各種異步的處理。一些大的操作,比如遠程獲取數據,操作一個大數據處理,這時候是不能馬上獲取到數據的。假設我們發送一個AJAX請求到接受到數據需要10秒鐘,那么從發送到接受數據這個時間段中,前端的處理時間其實是空閑,但是對于開發者來說這種時間是不能浪費了,所以我們可以在10秒鐘做很多同步的處理,同時等待異步的數據返回。所以我們需要監聽這個回調的數據在成功的時候能夠獲取到,或者設計一個返回后觸發處理的機制,當然原生的JavaScript對這個機制幾乎是沒有的。為了優化這個形成統一的異步處理方案,jQuery就開始設計了一個Deferred異步模型。
Deferred 提供了一個抽象的非阻塞的解決方案(如異步請求的響應),它創建一個promise對象,其目的是在未來某個時間點返回一個響應。簡單來說就是一個異步/同步回調函數的處理方案。
$.Deferred在jQuery代碼內部有四個模塊被使用,分別是“promise方法”、“DOM ready”、“Ajax模塊”及“動畫模塊”。
看看jQuery中的最常用的AJAX處理:
一:Ajax的改造
傳統的jQuery的AJAX操作的傳統寫法(1.5版之前):
$.ajax({ url: "aaron.html", success: function(){ alert("成功!"); }, error:function(){ alert("失敗!"); } })
$.ajax()接受一個對象參數,這個對象包含兩個方法:success方法指定操作成功后的回調函數,error方法指定操作失敗后的回調函數。
在1.5版本后通過新的Deferred引入就改成了:
$.ajax("aaron.html") .done(function(){ alert("成功"); }) .fail(function(){ alert("出錯"); });
把傳參的回調,換成了鏈式的寫法,這樣可讀性更高了。在jquery 1.5版后,通過$.ajax返回的不是XHR對象了,而是經過包裝的Deferred對象,所以就具有promise的一些規范。當然這種寫法到底是怎么做的,我們在后續的教程中會詳細的講解到。
二:提供一種方法來執行一個或多個對象的回調函數
在實際開發中,我們可能要發送多個異步的請求操作,我們需要等所有的異步都處理完畢后,才能繼續下一個動作。如右邊代碼所示。
所以我們這里要涉及一個等待的處理。我們自己要做一個計時器,每一個任務執行完畢后,都要觸發一次任務的檢測。當最后一個調用完畢了,我們就可以執行后面的動作,當前這里的寫法也會有些問題,比如錯誤的時候沒有處理。同樣的功能,我們換成Deferred就會很簡單了。
$.when($.ajax("a1.html"), $.ajax("a2.html")) .done(function(){ alert('2次回調都正確返回了') }) .fail(function(){ alert('出錯了'); });
這段代碼的意思是:先執行兩個操作$.ajax("a1.html")和$.ajax("a2.html"),如果都成功了,就運行done()指定的回調函數;如果有一個失敗或都失敗了,就執行fail()指定的回調函數。
三:可以混入任意的對象接口中
jQuery的Deferred最好用的地方,就是模塊化程度非常高,可以任意配合使用。
function task(name) { var dtd = $.Deferred(); setTimeout(function() { dtd.resolve(name) }, 1000) return dtd; } $.when(task('任務一'), task('任務二')).done(function() { alert('成功') })
把需要處理的異步操作,用Deferred對象給包裝一下,然后通過when方法收集異步的操作,最后再返回出done的成功,這樣的處理太贊了!
所以說,Deferred的引入,為處理事件回調提供了更加強大并且更靈活的編程模型。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報