jQuery中的deferred對象理解

一、deferred對象的含義

? ? 在以往過程中,我們想要在異步操作或耗時(shí)較長的同步操作完成后執(zhí)行某操作,這時(shí)我們往往會采取回調(diào)的方式進(jìn)行解決。如果進(jìn)行了多次回調(diào)操作會導(dǎo)致代碼復(fù)雜且難維護(hù),而jQuery中的deferred對象就是可以解決這種問題,總的來說deferred對象就是jQuery的回調(diào)函數(shù)解決方案。這也讓我聯(lián)想到了ES6的promise對象也有這樣的作用,下面我也會適當(dāng)?shù)睾虴S6的promise對象進(jìn)行類比。

二、deferred對象實(shí)戰(zhàn)

? ? 下面直接上代碼。

????var dtd = $.Deferred(); // 新建一個(gè)deferred對象 相當(dāng)于ES6的 new Promise()

  var wait = function(dtd){

    var tasks = function(){

      alert("執(zhí)行完畢!");

? ? ? ? ? ? ? ? ? ? ??dtd.resolve();?// 改變deferred對象的執(zhí)行狀態(tài) 相當(dāng)于ES6的 promise.resolve()

    };

    setTimeout(tasks,5000);

? ?????????????return dtd;

  };

現(xiàn)在,wait()函數(shù)返回的是deferred對象,這就可以加上鏈?zhǔn)讲僮髁恕?/p>

  $.when(wait(dtd))

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯(cuò)啦!"); });

運(yùn)行結(jié)果為:5秒后輸出"執(zhí)行完畢!",然后再輸出"哈哈,成功了!"

上面有一個(gè)問題就是??var dtd = $.Deferred()中的dtd是一個(gè)全局對象,可以在全局中改變它的狀態(tài),例如:

 $.when(wait(dtd))

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯(cuò)啦!"); });

? ??????dtd.resolve();

這就改變了dtd對象的執(zhí)行狀態(tài),因此導(dǎo)致done()方法立刻執(zhí)行,跳出"哈哈,成功了!"的提示框,等5秒之后再跳出"執(zhí)行完畢!"的提示框

為了避免這種情況,jQuery提供了deferred.promise()方法。它的作用是,在原來的deferred對象上返回另一個(gè)deferred對象,后者只開放與改變執(zhí)行狀態(tài)無關(guān)的方法(比如done()方法和fail()方法),屏蔽與改變執(zhí)行狀態(tài)有關(guān)的方法(比如resolve()方法和reject()方法),從而使得執(zhí)行狀態(tài)不能被改變。

以下是推薦的寫法:

var wait = function(dtd){

? ??????var dtd = $.Deferred(); //在函數(shù)內(nèi)部,新建一個(gè)Deferred對象

    var tasks = function(){

      alert("執(zhí)行完畢!");

      dtd.resolve(); // 改變Deferred對象的執(zhí)行狀態(tài)

????????????????};

????????????????setTimeout(tasks,5000);

    return dtd.promise(); // 返回promise對象

  };

$.when(wait())

  .done(function(){ alert("哈哈,成功了!"); })

  .fail(function(){ alert("出錯(cuò)啦!"); });

三、小結(jié)

(1)?$.Deferred()?生成一個(gè)deferred對象。相當(dāng)于ES6的new Promise()

(2)?deferred.done()?指定操作成功時(shí)的回調(diào)函數(shù)

(3)?deferred.fail()?指定操作失敗時(shí)的回調(diào)函數(shù)。相當(dāng)于ES6的Promise.prototype.catch()

(4)?deferred.promise()?沒有參數(shù)時(shí),返回一個(gè)新的deferred對象,該對象的運(yùn)行狀態(tài)無法被改變;接受參數(shù)時(shí),作用為在參數(shù)對象上部署deferred接口。

(5)?deferred.resolve()?手動改變deferred對象的運(yùn)行狀態(tài)為"已完成",從而立即觸發(fā)done()方法。相當(dāng)于ES6的Promise.resolve()

(6)deferred.reject()?這個(gè)方法與deferred.resolve()正好相反,調(diào)用后將deferred對象的運(yùn)行狀態(tài)變?yōu)?已失敗",從而立即觸發(fā)fail()方法。相當(dāng)于ES6的Promise.reject()

(7)?$.when()?為多個(gè)操作指定回調(diào)函數(shù)。相當(dāng)于ES6的Promise.all()

(8)deferred.then()有時(shí)為了省事,可以把done()和fail()合在一起寫,這就是then()方法。$.when($.ajax( "/main.php" )).then(successFunc, failureFunc )。相當(dāng)于ES6的Promise.prototype.then()

(9)deferred.always()? 這個(gè)方法也是用來指定回調(diào)函數(shù)的,它的作用是,不管調(diào)用的是deferred.resolve()還是deferred.reject(),最后總是執(zhí)行。相當(dāng)于ES6的Promise.prototype.finally()

參考自

【1】jQuery的deferred對象詳解

【2】http://api.jquery.com/category/deferred-object/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • jQuery的deferred對象詳解 作者:阮一峰 一、什么是deferred對象? 開發(fā)網(wǎng)站的過程中,我們經(jīng)常...
    JamHsiao_aaa4閱讀 353評論 0 0
  • 最近做項(xiàng)目,調(diào)用后端接口,需要等到2個(gè)ajax返回再執(zhí)行另一個(gè)ajax,首先想到的是使用promise,但是考慮...
    晴天小豬L閱讀 597評論 0 0
  • Promise 對象 Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,823評論 1 56
  • 有一天,我出了門外,我感覺到了很冷。幸好我媽媽給我穿上了厚的衣服。我說“媽媽現(xiàn)在是冬天嗎?”我媽媽說“是的。”我...
    李金陽愛閱讀 193評論 0 0

友情鏈接更多精彩內(nèi)容