jQuery的deferred學(xué)習(xí)

deferred對象簡介


原文鏈接
http://www.jb51.net/article/28054.htm


開發(fā)網(wǎng)站的過程中蚂四,我們經(jīng)常遇到某些耗時(shí)很長的javascript操作逻恐。其中态辛,既有異步的操作(比如ajax讀取服務(wù)器數(shù)據(jù)),也有同步的操作(比如遍歷一個(gè)大型數(shù)組)瓦哎,它們都不是立即能得到結(jié)果的奇昙。
通常的解決方法是欢瞪,為它們指定回調(diào)函數(shù)(callback)。即事先規(guī)定碉纺,一旦它們運(yùn)行結(jié)束船万,應(yīng)該調(diào)用哪些函數(shù)细层。
但是,在回調(diào)函數(shù)方面唬涧,jQuery的功能非常弱疫赎。為了改變這一點(diǎn),jQuery開發(fā)團(tuán)隊(duì)就設(shè)計(jì)了deferred對象碎节。
簡單說捧搞,deferred對象就是jQuery的回調(diào)函數(shù)解決方案。在英語中狮荔,defer的意思是"延遲"胎撇,所以deferred對象的含義就是"延遲"到未來某個(gè)點(diǎn)再執(zhí)行。

ajax操作的鏈?zhǔn)綄懛?/p>

jQuery的ajax操作殖氏,傳統(tǒng)寫法是這樣的:

$.ajax({
  url: "test.html",
  success: function({       
            alert("哈哈晚树,成功了!");  
  },
  error:function(){       
            alert("出錯(cuò)啦雅采!");    
   }
});

在上面的代碼中爵憎,$.ajax()接受一個(gè)對象參數(shù),這個(gè)對象包含兩個(gè)方法:success方法指定操作成功后的回調(diào)函數(shù)婚瓜,error方法指定操作失敗后的回調(diào)函數(shù)宝鼓。
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery巴刻,返回的是XHR對象愚铡,你沒法進(jìn)行鏈?zhǔn)讲僮鳎蝗绻哂?.5.0版本胡陪,返回的是deferred對象沥寥,可以進(jìn)行鏈?zhǔn)讲僮鳌?/p>

鏈?zhǔn)叫聦懛ǎ?/p>

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

回調(diào)函數(shù)可以添加任意多個(gè),它們按照添加順序執(zhí)行柠座。

普通操作的回調(diào)函數(shù)接口

deferred對象的最大優(yōu)點(diǎn)邑雅,就是它把這一套回調(diào)函數(shù)接口,從ajax操作擴(kuò)展到了所有操作愚隧。也就是說蒂阱,任何一個(gè)操作----不管是ajax操作還是本地操作,也不管是異步操作還是同步操作----都可以使用deferred對象的各種方法狂塘,指定回調(diào)函數(shù)录煤。

我們來看一個(gè)具體的例子。假定有一個(gè)很耗時(shí)的操作wait:
var wait = function(){
        var tasks = function(){
                alert('done');        
        };
        setTimeout(tasks, 5000);
};

**使用$.when:**
$.when(wait()).done(function{}).fail(function(){});
 但是荞胡,有一個(gè)問題妈踊。$.when()的參數(shù)只能是deferred對象,所以必須對wait進(jìn)行改寫:
var dtd = $.Deferred();
var wait = function(dtd) {
        var tasks = function(){
                dtd.resolve();
        };
        setTimeout(tasks, 5000);
        return dtd.promise();
}

***注意***
 首先泪漂,最后一行不能直接返回dtd廊营,必須返回[dtd.promise()](http://api.jquery.com/deferred.promise/)歪泳。原因是jQuery規(guī)定,任意一個(gè)deferred對象有三種執(zhí)行狀態(tài)----未完成露筒,已完成和已失敗呐伞。如果直接返回dtd,$.when()的默認(rèn)執(zhí)行狀態(tài)為"已完成"慎式,立即觸發(fā)后面的done()方法伶氢,這就失去回調(diào)函數(shù)的作用了。dtd.promise()的目的瘪吏,就是保證目前的執(zhí)行狀態(tài)----也就是"未完成"----不變癣防,從而確保只有操作完成后,才會(huì)觸發(fā)回調(diào)函數(shù)掌眠。
    其次蕾盯,當(dāng)操作完成后,必須手動(dòng)改變Deferred對象的執(zhí)行狀態(tài)蓝丙,否則回調(diào)函數(shù)無法觸發(fā)级遭。[dtd.resolve()](http://api.jquery.com/deferred.resolve/)的作用,就是將dtd的執(zhí)行狀態(tài)從"未完成"變成"已完成"迅腔,從而觸發(fā)done()方法装畅。
    最后別忘了靠娱,修改完wait之后沧烈,調(diào)用的時(shí)候就必須直接傳入dtd參數(shù)。

$.when(wait(dtd)).don(function(){}).fail(function(){});

**使用$.Deferred()**
$.Deferred(wait).done(function(){}).fail(function(){});
jQuery規(guī)定像云,$.Deferred()可以接受一個(gè)函數(shù)作為參數(shù)锌雀,該函數(shù)將在$.Deferred()返回結(jié)果之前執(zhí)行。并且迅诬,$.Deferred()所生成的Deferred對象將作為這個(gè)函數(shù)的默認(rèn)參數(shù)腋逆。

**在wait對象上部署deferred接口**
var dtd = $.Derferred();
var wait = function(dtd){
        var tasks = function(){
                dtd.resolve();
        };
        setTimeout(tasks, 5000);
};
dtd.promise(wait);
wait.done(function(){}).fail(function(){});
wait(dtd);


>Deferred對象方法總結(jié)

(1)[$.Deferred()](http://api.jquery.com/category/deferred-object/)生成一個(gè)deferred對象。
 〕薮(2)[deferred.done()](http://api.jquery.com/deferred.done/)指定操作成功時(shí)的回調(diào)函數(shù)
 〕颓浮(3)[deferred.fail()](http://api.jquery.com/deferred.fail/)指定操作失敗時(shí)的回調(diào)函數(shù)
  (4)[deferred.promise()](http://api.jquery.com/deferred.promise/)沒有參數(shù)時(shí)俏蛮,作用為保持deferred對象的運(yùn)行狀態(tài)不變撑蚌;接受參數(shù)時(shí),作用為在參數(shù)對象上部署deferred接口搏屑。
 ≌俊(5)[deferred.resolve()](http://api.jquery.com/deferred.resolve/)手動(dòng)改變deferred對象的運(yùn)行狀態(tài)為"已完成",從而立即觸發(fā)done()方法辣恋。
 ×恋妗(6)[$.when()](http://api.jquery.com/jQuery.when/)為多個(gè)操作指定回調(diào)函數(shù)模软。
除了這些方法以外,deferred對象還有三個(gè)重要方法饮潦,上面的教程中沒有涉及到燃异。
  (7)[deferred.then()](http://api.jquery.com/deferred.then/)
有時(shí)為了省事继蜡,可以把done()和fail()合在一起寫特铝,這就是then()方法。
  $.when($.ajax( "/main.php" ))
  **.then(successFunc, failureFunc );**
如果then()有兩個(gè)參數(shù)壹瘟,那么第一個(gè)參數(shù)是done()方法的回調(diào)函數(shù)鲫剿,第二個(gè)參數(shù)是fail()方法的回調(diào)方法。如果then()只有一個(gè)參數(shù)稻轨,那么等同于done()灵莲。
  (8)[deferred.reject()](http://api.jquery.com/deferred.reject/)
這個(gè)方法與deferred.resolve()正好相反殴俱,調(diào)用后將deferred對象的運(yùn)行狀態(tài)變?yōu)?已失敗"政冻,從而立即觸發(fā)fail()方法。
 ∠哂(9)[deferred.always()](http://api.jquery.com/deferred.always/)
這個(gè)方法也是用來指定回調(diào)函數(shù)的明场,它的作用是,不管調(diào)用的是deferred.resolve()還是deferred.reject()李丰,最后總是執(zhí)行苦锨。
  $.ajax( "test.html" )
  .always( function() { alert("已執(zhí)行!");} );














最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趴泌,一起剝皮案震驚了整個(gè)濱河市舟舒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗜憔,老刑警劉巖秃励,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吉捶,居然都是意外死亡夺鲜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門呐舔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來币励,“玉大人,你說我怎么就攤上這事滋早¢螅” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵杆麸,是天一觀的道長搁进。 經(jīng)常有香客問我浪感,道長,這世上最難降的妖魔是什么饼问? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任影兽,我火速辦了婚禮,結(jié)果婚禮上莱革,老公的妹妹穿的比我還像新娘峻堰。我一直安慰自己,他們只是感情好盅视,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布捐名。 她就那樣靜靜地躺著,像睡著了一般闹击。 火紅的嫁衣襯著肌膚如雪镶蹋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天赏半,我揣著相機(jī)與錄音贺归,去河邊找鬼。 笑死断箫,一個(gè)胖子當(dāng)著我的面吹牛拂酣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仲义,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼婶熬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了光坝?” 一聲冷哼從身側(cè)響起尸诽,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盯另,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洲赵,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸳惯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叠萍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芝发。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖苛谷,靈堂內(nèi)的尸體忽然破棺而出辅鲸,到底是詐尸還是另有隱情,我是刑警寧澤腹殿,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布独悴,位于F島的核電站例书,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏刻炒。R本人自食惡果不足惜决采,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坟奥。 院中可真熱鬧树瞭,春花似錦、人聲如沸爱谁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽访敌。三九已至厨埋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捐顷,已是汗流浹背荡陷。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迅涮,地道東北人废赞。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像叮姑,于是被迫代替她去往敵國和親唉地。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容