jquery 中的 deferred 對象

參考連接

  1. jQuery API中文文檔
  2. jQuery.Deferred
  3. jQuery.when
  4. jQuery的deferred對象詳解
  5. jQuery deferred 對象的 promise 方法
  6. jQuery中的Deferred-詳解和使用

什麼是 deferred 對象?

延遲對象,在jQuery的1.5引入,是經過調用jQuery.Deferred()方法建立一個可鏈式調用的工具對象。 它能夠註冊多個回調到回調隊列, 調用回調隊列,準備代替任何同步或異步函數的成功或失敗狀態。——jQuery API中文文檔
簡單說,deferred對象就是jQuery的回調函數解決方案。在英語中,defer的意思是"延遲",因此deferred對象的含義就是"延遲"到將來某個點再執行。它解決了如何處理耗時操做的問題,對那些操做提供了更好的控制,以及統一的編程接口。——阮一峯

deferred 對象的主要功能

  1. ajax 操做的鏈式寫法php

    $.ajax("test.html")
       .done(function(){ alert("success"); })
       .fail(function(){ alert("error"); });

    $.ajax() 操做完成後,若是使用的是低於1.5.0版本的jQuery,返回的是XHR對象,沒法進行鏈式操做;若是是高於1.5.0版本,返回的是deferred對象,能夠進行鏈式操做。能夠看到,done() 至關於 success 方法,fail() 至關於 error 方法。採用鏈式寫法之後,代碼的可讀性大大提升。css

    這裏着重強調一下 jqXHR 對象,從 jQuery 1.5 開始, $.ajax() 返回的 jqXHR對象 自己就是 deferred 對象,所以能夠像上面代碼中那樣進行鏈式調用。html

    從 jQuery 1.5 開始,$.ajax()返回的jqXHR對象 實現了 Promise 接口, 使它擁有了 Promise 的全部屬性,方法和行爲。(見Deferred object獲取更多信息)。爲了讓回調函數的名字統一,便於在$.ajax()中使用。jqXHR也提供.error() .success()和.complete()方法。這些方法都帶有一個參數,該參數是一個函數,此函數在 $.ajax()請求結束時被調用,而且這個函數接收的參數,與調用 $.ajax()函數時的參數是一致。這將容許你在一次請求時,對多個回調函數進行賦值,甚至容許你在請求已經完成後,對回調函數進行賦值(若是該請求已經完成,則回調函數會被馬上調用)。

    注意事項: jqXHR.success(), jqXHR.error(), 和 jqXHR.complete() 回調從 jQuery 1.8開始 被棄用過期,從jQuery 3.0開始被刪除,你可使用 jqXHR.done(), jqXHR.fail(), 和 jqXHR.always() 代替。jquery

  2. 指定同一操做的多個回調函數
    deferred 對象的一大好處,就是它容許你自由添加多個回調函數。仍是以上面的代碼爲例,若是ajax操做成功後,除了原來的回調函數,我還想再運行一個回調函數,怎麼辦?很簡單,直接把它加在後面就好了。程序員

    $.ajax("test.html")
       .done(function(){ alert('success'); })
       .fail(function(){ alert('error'); })
        .done(function(){ alert('第二個回調函數!'); });

    回調函數能夠添加任意多個,它們按照添加順序執行。web

  3. 爲多個操做指定回調函數
    deferred 對象的另外一大好處,就是它容許你爲多個事件指定一個回調函數,這是傳統寫法作不到的。ajax

    請看下面的代碼,它用到了一個新的方法 jQuery.when()編程

    $.when($.ajax("test1.html"), $.ajax("test2.html"))
       .done(function(){ alert('success'); })
       .fail(function(){ alert('error'); });

    這段代碼的意思是,先執行兩個操做$.ajax("test1.html")和$.ajax("test2.html"),若是都成功了,就運行done()指定的回調函數;若是有一個失敗或都失敗了,就執行fail()指定的回調函數。api

    $.when() 方法的使用具體 參見文檔promise

  4. 普通操做的回調函數接口
    deferred 對象的最大優勢,就是它把這一套回調函數接口,從ajax操做擴展到了全部操做。也就是說,任何一個操做----不論是ajax操做仍是本地操做,也不論是異步操做仍是同步操做----均可以使用deferred對象的各類方法,指定回調函數。

    咱們來看一個具體的例子,爲一個很耗時的操做 wait 指定回調函數:

    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('success'); })
        .fail(function () { alert('error'); });

    另外一種作法是直接將 wait 函數傳入 $.Deferred()

    $.Deferred(wait)
       .done(function(){ alert('success'); })
       .fail(function(){ alert('error'); });

    jQuery 規定,$.Deferred() 能夠接受一個函數名(注意,是函數名)做爲參數,$.Deferred() 所生成的 deferred 對象將做爲這個函數的默認參數。

    更具體的信息請參見 阮一峯的文檔

deferred 對象的方法

  1. $.Deferred() 生成一個 deferred 對象。
    jQuery.Deferred( [beforeStart ] ) 工廠函數建立一個新的deferred對象。

    描述: 一個工廠函數,這個函數返回一個鏈式實用對象,用返回對象方法來在回調隊列中註冊多個回調, 調用回調隊列,傳遞任何同步或異步函數的成功或失敗狀態。

    beforeStart : 類型 Function( Deferred deferred ),一個構造函數返回以前調用的函數。

    jQuery.Deferred 方法能夠傳遞一個可選的函數, 這個函數在方法返回以前調用, 而且會把新的 deferred(延遲)對象做爲 this 對象,將其做爲第一個參數傳遞給函數。例如,被調用的函數可使用 deferred.then() 綁定回調。
  2. deferred.done() 指定操做成功時的回調函數。
  3. deferred.fail() 指定操做失敗時的回調函數。
  4. deferred.promise() 沒有參數時,返回一個新的 deferred。 對象,該對象的運行狀態沒法被改變;接受參數時,做用爲在參數對象上部署 deferred 接口。
  5. deferred.resolve() 手動改變 deferred 對象的運行狀態爲"已完成",從而當即觸發 done() 方法。

    一個 Deferred(延遲)對象開始於 pending 狀態。 任何回調使用 deferred.then(), deferred.always(), deferred.done(), 或者 deferred.fail() 添加到這個對象都是排隊等待執行。調用 deferred.resolve() 轉換 Deferred(遞延)到 resolved(解決)的狀態,並當即執行設置中任何的 doneCallbacks。調用 deferred.reject() 轉換 Deferred(遞延)到 rejected(拒絕)的狀態,並當即執行設置中任何的 failCallbacks。一旦對象已經進入瞭解決或拒絕狀態,它處於該狀態。回調仍然能夠添加到解決或拒絕 Deferred(遞延)- 他們會當即執行。

    $.ajax() 返回的 jqXHR 對象 會根據請求返回的結果,自動改變自身的執行狀態。可是,對於其餘經過 $.Deferred() 方法生成的 deferred 對象,它們的執行狀態必須由程序員手動指定,由代碼決定在何時觸發回調函數。

  6. deferred.reject() 這個方法與 deferred.resolve() 正好相反,調用後將 deferred 對象的運行狀態變爲"已失敗",從而當即觸發 fail() 方法。
  7. $.when() 爲多個操做指定回調函數。
  8. deferred.then() 方法
    有時爲了省事,能夠把 done()fail() 合在一塊兒寫,這就是 then() 方法。

    $.when($.ajax( '/main.php' ))
       .then(successFunc, failureFunc);

    若是 then() 有兩個參數,那麼第一個參數是 done() 方法的回調函數,第二個參數是 fail() 方法的回調方法。若是 then() 只有一個參數,那麼等同於 done()

  9. deferred.always() 方法
    這個方法也是用來指定回調函數的,它的做用是,無論調用的是 deferred.resolve() 仍是 deferred.reject(),最後老是執行。

    $.ajax( 'test.html' )
        .always( function() { alert('已執行!');} );

    更多信息請參見 jQuery API中文文檔

相關文章
相關標籤/搜索