jQuery.deferred詳解

deferred是什么?

deferred 翻譯為推遲,在jQuery 1.5中引入的Deferred對象是通過調(diào)用jQuery.Deferred()方法創(chuàng)建的可鏈接實用程序?qū)ο蟆K梢栽诨卣{(diào)隊列中注冊多個回調(diào)函數(shù)对供,調(diào)用回調(diào)隊列,并中繼任何同步或異步函數(shù)的成功或失敗狀態(tài)笔宿。

deferred能為我們解決什么問題犁钟?

我們常常會遇到這種問題,
定義一個變量泼橘, 在a函數(shù)中為它賦值 涝动,在b函數(shù)中調(diào)用它 。
如下場景:

var current  = 0;
function a() {
  setTimeout(function () {
    current = 6;
  }, 500);
}
function b() {
  a();
  console.log(current);
}
b(); // 0

b函數(shù)沒有等待a函數(shù)賦值成功便執(zhí)行了炬灭,導致console出的值是current 的初始值醋粟。
為了解決這個問題,我們肯定想到回調(diào)重归。

var current  = 0;
function a(callback) {
  setTimeout(function () {
    current = 6;
    callback();
  }, 500);
}
function b() {
  a(function(){
    console.log(current);
  });
}
b(); // 0

通過回調(diào)函數(shù)米愿,b函數(shù)得到了賦值6。

那么有更多的函數(shù)在b函數(shù)之前對current 賦值鼻吮,那么....

function b() {
  a(function(){
    c(function(){
      d(function(){
          console.log(current);
       })
     })
  });
}

上面的情況讓我們的代碼變的復(fù)雜育苟、可讀性很差。
而deferred對象的產(chǎn)生是為jQuery回調(diào)函數(shù)提供解決方案椎木。

$.when(a, c, d)
    .then(b);

這樣既簡化了代碼违柏,可讀性也增強了很多。_

jQuery deferred使用方法及使用場景香椎?

Deferred對象是可鏈接的漱竖,類似于jQuery對象是可鏈接的,但它有自己的方法畜伐。創(chuàng)建Deferred對象后馍惹,可以使用以下任何方法,直接從對象創(chuàng)建鏈接或?qū)ο蟊4嬖谧兞恐性僬{(diào)用該變量創(chuàng)建一個或多個方法玛界。

deferred.always()

當Deferred對象被resolved或rejected時万矾,將會調(diào)用的函數(shù)。

deferred.catch()

當Deferred對象被rejected時慎框,將會調(diào)用的函數(shù)勤众。

deferred.done()

當Deferred對象被resolved時,將會調(diào)用的函數(shù)鲤脏。

deferred.fail()

當Deferred對象被rejected時们颜,將會調(diào)用的函數(shù)。

deferred.isRejected()

測定Deferred對象是否已被rejected猎醇。

deferred.isResolved()

測定Deferred對象是否已被resolved窥突。

deferred.notify()

根據(jù)給定的 args參數(shù) 調(diào)用Deferred對象上進行中的回調(diào)

deferred.notifyWith()

根據(jù)給定的文本和args參數(shù) 調(diào)用Deferred對象上進行中的回調(diào)

 deferred.pipe()

用用于過濾 and/or 鏈式Deferred對象的工具方法。

deferred.progress()

當Deferred對象生成正在執(zhí)行中的進度通知時, 將會調(diào)用的函數(shù)硫嘶。

deferred.promise()

返回Deferred Promise對象阻问。

deferred.reject()

根據(jù)給定的 args參數(shù) Reject Deferred對象并調(diào)用所有失敗回調(diào)函數(shù)。

deferred.rejectWith()

根據(jù)給定的文本和args參數(shù) Reject Deferred對象并調(diào)用所有失敗回調(diào)函數(shù)沦疾。

deferred.resolve()

根據(jù)給定的 args參數(shù) Resolve Deferred對象并調(diào)用所有成功回調(diào)函數(shù)称近。

deferred.resolveWith()

根據(jù)給定的文本和args參數(shù) Resolve Deferred對象并調(diào)用所有成功回調(diào)函數(shù)第队。

deferred.state()

測定Deferred對象的當前狀態(tài)。

deferred.then()

當Deferred對象被rejected刨秆、resolve凳谦、正在進行中時,將會調(diào)用的函數(shù)衡未。

jQuery.when()

為一種基于零個或多個對象(通常為表示異步事件的Deferred對象)提供執(zhí)行回調(diào)函數(shù)的方法尸执。

.promise()

返回一個Promise對象以觀察綁定到集合的某個類型的所有操作何時完成。

deferred對象使用resolve()函數(shù)改變了Deferred對象的當前狀態(tài)為完成并執(zhí)行與done()相關(guān)的函數(shù)缓醋。reject()函數(shù)改變了Deferred對象的當前狀態(tài)為失敗并執(zhí)行與fail()相關(guān)的函數(shù)如失。
下面是一個關(guān)于deferred的簡單例子:

var dtd = $.Deferred();     //生成一個deferred對象。
var wait =function(dtd){    //定義函數(shù) 并傳入deferred對象送粱。
  alert("執(zhí)行了");    //函數(shù)體
  dfd.resolve();   //手動改變deferred對象的運行狀態(tài)從“未完成”到"已完成"褪贵,立即觸發(fā)done()方法。
};
$.when(wait(dtd))    //$.when可以為多個操作指定同一個回調(diào)函數(shù) 以逗號分隔開
.done(function(){ alert("成功"); })   //指定操作成功時的回調(diào)函數(shù)
.fail(function(){ alert("失敗"); });    //指定操作失敗時的回調(diào)函數(shù)
.then(function(){ alert("成功失敗");})   //done(),fail(),progress()操作成功或失敗執(zhí)行的回調(diào)函數(shù)

暴露在外面的deferred 為全局對象抗俄,所以它的執(zhí)行狀態(tài)可以從外部改變竭鞍。為了不把 deferred 對象直接暴露出來,函數(shù)體最后需返回 deferred.promise() 返回的對象只會暴露判斷和處理狀態(tài)的方法 橄镜,而不會暴露改變狀態(tài)的方法如:
<pre>
var wait = function(){
var dtd = $.Deferred(); // 新建一個deferred對象
var tasks = function(){
alert("執(zhí)行完畢偎快!");
dtd.resolve(); // 改變deferred對象的執(zhí)行狀態(tài)
};
setTimeout(tasks, 500);
return dtd.promise();
};
$.when( wait())
.done(function(){ alert("成功"); })
.fail(function(){ alert("失敗"); });
</pre>

在ajax中應(yīng)用的實例:
<pre>
function API(api_url, method, data) {
var dtd = $.Deferred();
$.ajax({
url: api_url,
type: method,
data: data,
success: function (response) {
dtd.resolve(response);
},
error: function (error) {
dtd.reject(error);
}
});
return dtd.promise();
}
API()
.done(function (response) {
console.log('成功');
})
.fail(function (error) {
console.log('失敗');
})
</pre>

jQuery deferred的優(yōu)點:

可以給一個操作提供多個回調(diào)函數(shù)。
<pre>
complete1()
.done(function(){ alert("first success callback!");} )
.fail(function(){ alert("there is an error!"); } )
.done(function(){ alert("second success callback!");} );
</pre>
也可以給多個操作提供同一個回調(diào)函數(shù)洽胶。
<pre>
$.when(complete1() , complete2())
.done(function(){ alert("success");} )
.fail(function(){ alert("error"); } )
</pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晒夹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子姊氓,更是在濱河造成了極大的恐慌丐怯,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翔横,死亡現(xiàn)場離奇詭異读跷,居然都是意外死亡,警方通過查閱死者的電腦和手機禾唁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門效览,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荡短,你說我怎么就攤上這事丐枉。” “怎么了掘托?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵瘦锹,是天一觀的道長。 經(jīng)常有香客問我,道長弯院,這世上最難降的妖魔是什么辱士? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮听绳,結(jié)果婚禮上颂碘,老公的妹妹穿的比我還像新娘。我一直安慰自己辫红,他們只是感情好凭涂,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布祝辣。 她就那樣靜靜地躺著贴妻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蝙斜。 梳的紋絲不亂的頭發(fā)上名惩,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音孕荠,去河邊找鬼娩鹉。 笑死,一個胖子當著我的面吹牛稚伍,可吹牛的內(nèi)容都是我干的弯予。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼鳖宾,長吁一口氣:“原來是場噩夢啊……” “哼蒙畴!你這毒婦竟也來了轩缤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤呼寸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猴贰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體对雪,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年米绕,在試婚紗的時候發(fā)現(xiàn)自己被綠了瑟捣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡栅干,死狀恐怖蝶柿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情非驮,我是刑警寧澤交汤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響芙扎,放射性物質(zhì)發(fā)生泄漏星岗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一戒洼、第九天 我趴在偏房一處隱蔽的房頂上張望俏橘。 院中可真熱鬧,春花似錦圈浇、人聲如沸寥掐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽召耘。三九已至,卻和暖如春褐隆,著一層夾襖步出監(jiān)牢的瞬間污它,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工庶弃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衫贬,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓歇攻,卻偏偏與公主長得像固惯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缴守,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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

  • 抽象來說葬毫,deferreds 可以理解為表示需要長時間才能完成的耗時操作的一種方式,相比于阻塞式函數(shù)它們是異步的斧散,...
    北方蜘蛛閱讀 1,547評論 1 5
  • Promise 的含義 一句話概括一下promise的作用:可以將異步操作以同步操作的流程表達出來供常,避免了層層嵌套...
    雪萌萌萌閱讀 5,483評論 0 7
  • 請移步: https://blog.cdswyda.com/post/20160923
    依韻宵音閱讀 392評論 0 6
  • JQuery 中利用 Deferred 對象提供類似 ES2016(aka. es7) 中 Promise 的功能...
    鳳歌閱讀 482評論 0 2
  • 前言 這幾天不顧死活只關(guān)注自己,硬生生的推了幾篇科技小軟文鸡捐,于是乎有朋友紛紛后臺留言問關(guān)于San Diego的旅行...
    隔壁陽臺上的貓閱讀 377評論 0 0