最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jQuery的promise與deferred對象在異步回調(diào)中的作用

 更新時間:2016年05月03日 15:47:02   作者:小渝人兒  
這篇文章主要介紹了jQuery的promise與deferred對象在異步回調(diào)中的作用,需要的朋友可以參考下

一、前言

為了讓前端們從回調(diào)的地獄中回到天堂, jQuery 也引入了 Promise 的概念。 Promise 是一種令代碼異步行為更加優(yōu)雅的抽象,有了它,我們就可以像寫同步代碼一樣去寫異步代碼。 jQuery 從1.5版本開始實現(xiàn)了 CommonJS Promise/A 規(guī)范這一重量級方案,不過沒有嚴(yán)格按照規(guī)范進行實現(xiàn),有一些API上的差異。

好,讓我們來看看他們的特性吧( 本文示例基于jquery 1.8版本以上 )。

二、示例

以前寫動畫時,我們通常是這么干的:

$('.animateEle').animate({
 opacity:'.5'
}, 4000,function(){
 $('.animateEle2').animate({
  width:'100px'
 },2000,function(){
  // 這樣太傷了
  $('.animateEle3').animate({
   height:'0'
  },2000);
 });
});

假如這么使用回調(diào)的話,那就太傷了。幸好,還有一些現(xiàn)成的 Promise 解決方案來優(yōu)雅地解決這種問題。

我們看看 jQuery 提供的解決辦法。

var animate1 = function() {
 return $('.animateEle1').animate({opacity:'.5'},4000).promise();
};
var animate2 = function() {
 return $('.animateEle2').animate({width:'100px'},2000).promise();
};
var animate3 = function(){
 return $('.animateEle3').animate({height:'0'},2000).promise();
};
// so easy,有木有,so clear,有木有
$.when(animate1()).then(animate2).then(animate3);

很明顯,更改后的代碼更易懂易讀了。

但是,上面的代碼,有些細節(jié)的東西并沒有透露,一不小心,就容易出錯,得不到我們想要的順序完成動畫的效果。下面讓我們來全面理解 jQuery 提供的 promise 和 deferred 對象的方法,看看到底如何使用。

三、promise和deffered對象方法

promise 對象其實就是 deferred 對象的特例,因為 promise 對象不能更改異步狀態(tài),而 deferred 對象可以。這點在他們的方法設(shè)計上,有著明顯的體現(xiàn)。

1.promise對象方法

通常,對于DOM,動畫,ajax相關(guān)方法,我們都可以使用 promise 方法。調(diào)用 promise 方法,返回的是 promise 對象??梢枣?zhǔn)秸{(diào)用 promise 方法。

promise對象常見的方法有三個 : done , fail , then 。

其它的方法就不要去記了, jquery 這里的接口方法太多了,在我看來挺啰嗦的,就跟早期的事件方法綁定一樣, live , delegate , bind ,最終不是都歸為 on 來管了么。

代碼示例,如下:

(1)DOM使用 promise 方法:

var box=$('#box');
box.promise().done(function(ele){
  console.log(ele);//jQuery box
});

(2)Ajax使用 promise 方法(默認返回一個 promise 對象,所以可以不必顯式調(diào)用 promise 方法):

$.post('/',{}).done(function(data){
  console.log('請求成功');
}).fail(function(){
  console.log('請求錯誤');
});

動畫示例已有,就不重復(fù)列出了。

2.deferred對象方法

那么Deferred和Promise之間有什么區(qū)別呢?正如你在前面看到的,一個promise就是一個由異步函數(shù)返回的對象。當(dāng)你想要自己編寫一個這樣的函數(shù)時你需要使用一個deferred。

一個deferred對象能做的和一個promise對象差不多,但是它有兩個函數(shù)來觸發(fā)done()和fail()函數(shù)。

一個deferred對象擁有一個resolve()函數(shù)來處理一個成功的結(jié)果并執(zhí)行與done()相關(guān)的函數(shù)。reject()函數(shù)則用來處理失敗的結(jié)果并執(zhí)行與fail()相關(guān)的函數(shù)。

你可以給resolve()和reject()函數(shù)都提供參數(shù),然后它們都將傳遞給與done()和fail()相關(guān)的回調(diào)函數(shù)。

promise對象沒有resolve()和reject()函數(shù)。這是因為你將promise放到了其他的腳本中并且你也不想promise去resolve或者reject一個promise。

下面是一個關(guān)于deferred的簡單例子。html僅僅是一個簡單的擁有id屬性為”result”的空div。

$('#result').html('waiting...');

var promise = wait();
promise.done(result);

function result() {
 $('#result').html('done');
}

function wait() {
 var deferred = $.Deferred();

 setTimeout(function() {
  deferred.resolve();
 }, 2000);

 return deferred.promise();
}  

其中,wait()函數(shù)返回了一個promise。它將在2s之后被解析。除了setTimeout之外,異步函數(shù)中所有的東西都能這樣使用,比如 動畫,Web worker等等。wait()函數(shù)中的代碼應(yīng)該很清晰,我們使用了deferred對象,但是我們返回了一個限制的promise對象。

對于 deferred 對象呢,也就是使用 $.Deferred() 方法,以及 $.when() 等方法創(chuàng)造出來的對象,有如下的常用方法:

resolve , reject , notify ;
done , fail , progress ;

另外還有 promise 、 then 和 always 方法。

之所以這么排版,是因為他們是對應(yīng)的,也就是說: resolve 方法會觸發(fā) done 的回調(diào)執(zhí)行, reject 會觸發(fā) fail 的回調(diào), notify 會觸發(fā) progress 的回調(diào)。

直接看代碼:

var wait = function(ms) {
 var dtd = $.Deferred();
 setTimeout(dtd.resolve, ms);
 // setTimeout(dtd.reject, ms);
 // setTimeout(dtd.notify, ms);
 return dtd.promise(); //此處也可以直接返回dtd
};

wait(2500).done(function() {
 console.log('haha,師太,你可讓老衲久等了');
}).fail(function() {
 console.log('失敗了');
}).progress(function(res) {
 console.log('等待中...');
});

我們看到了,上面的代碼中,在 wait 函數(shù)中,返回的是個 promise 對象,而不是 deferred 對象。

要知道, promise 對象是沒有 resolve , reject , notify 等方法的,也就意味著,你無法針對 promise 對象進行狀態(tài)更改,只能在 done 或 fail 中進行回調(diào)配置。所以,你如果這么調(diào)用 wait(2500).resolve() 將會報錯,因為 wait(2500) 返回的是個 promise 對象,不存在 resolve 方法。

但是,這么做,有個好處,我們把 dtd 這個 deferred 對象放在了 wai t函數(shù)中,作為了局部變量,避免了全局的污染;進一步通過 promise 方法,轉(zhuǎn)化 dtd 這個 deferred 對象為 promise 對象,避免了函數(shù) wait 外部可能發(fā)生的狀態(tài)更改(假如我們確實有這個需求)。

比如:

var wait = function(ms) {
 var dtd = $.Deferred();
 setTimeout(dtd.resolve, ms);
 // setTimeout(dtd.reject, ms);
 // setTimeout(dtd.notify, ms);
 return dtd; //此處也可以直接返回dtd
};

wait(2500).reject().fail(function(){
 console.log('失敗了...............');
});

我們在外部更改了 wait 返回的 deferred 對象的狀態(tài),這樣必然觸發(fā)該對象的 fail 回調(diào)函數(shù)。

對于 always 方法,從字面意思上就很容易理解, deferred 對象無論是 resolve 還是 reject ,都會觸發(fā)該方法的回調(diào)。

3.其它共性

此處講講 then 和 $.when 方法的使用。它們對 promise 對象也適用。

$.when 方法接受多個 deferred 對象或者純javascript對象,返回 promise 對象。
then 方法依次接受三個回調(diào),分別為 deferred 對象 resolve , reject , notify 后觸發(fā)的回調(diào),返回一個 promise 對象。注意,必須傳入函數(shù),而該函數(shù)只有返回一個 promise 對象,才能夠讓異步事件按照預(yù)期順序來執(zhí)行。
我們來看看最開始的動畫示例代碼, $.when(animate1()).then(animate2).then(animate3) , $.when 方法中接受了一個 animate1 的函數(shù)執(zhí)行結(jié)果,也就是得到了一個 promise 對象,而后的 then 中,則只是接受了一個變量名,這樣得到的結(jié)果是一個匿名的函數(shù)體,而該函數(shù)中返回的是 promise 對象。正好符合了我們對 then 接受參數(shù)的要求。

假如我們把執(zhí)行語句改成: $.when(animate1()).then(animate2()).then(animate3()) ,這樣造成的結(jié)果就是三個動畫同步執(zhí)行了。與 $.when(animate1(),animate2(),animate3()) 無異。

既然 then 是如此要求,那么與 then 方法類似的 done , fail , progress 也是一樣的。

相關(guān)文章

  • 基于jquery的橫向滾動條(滑動條)

    基于jquery的橫向滾動條(滑動條)

    ASP.Net的GridView本身不帶滾動條,可通過Panel實現(xiàn)。但是Windows自帶的橫向滾動條只支持顯示在下方,為了使用方便,需要在上下方都顯示橫向滾動條。
    2011-02-02
  • jquery+h5實現(xiàn)九宮格抽獎特效(前后端代碼)

    jquery+h5實現(xiàn)九宮格抽獎特效(前后端代碼)

    這篇文章主要為大家詳細介紹了jquery+h5實現(xiàn)九宮格抽獎特效,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • jquery 圖片輪換效果

    jquery 圖片輪換效果

    重寫了昨天的圖片輪換,加入了自動切換效果,改變了布局,增強了可定制性,當(dāng)然,還是有點小小的問題,在IE 6+,chrome,firfox3.68下測試正常運行
    2010-07-07
  • Jquery實現(xiàn)瀑布流布局(備有詳細注釋)

    Jquery實現(xiàn)瀑布流布局(備有詳細注釋)

    這篇文章主要介紹了Jquery實現(xiàn)瀑布流布局的方法,可實現(xiàn)圖片的動態(tài)加載功能,且代碼備有詳細注釋便于理解,需要的朋友可以參考下
    2015-07-07
  • 解決IE7中使用jQuery動態(tài)操作name問題

    解決IE7中使用jQuery動態(tài)操作name問題

    IE7中無法使用Jquery動態(tài)操作頁面元素的name屬性,怎么解決這個問題呢?下面小編給大家?guī)砹私鉀QIE7中使用jQuery動態(tài)操作name問題,需要的朋友參考下吧
    2017-08-08
  • jquery中用函數(shù)來設(shè)置css樣式

    jquery中用函數(shù)來設(shè)置css樣式

    本文主要對jquery中用函數(shù)來設(shè)置css樣式的方法進行詳細介紹,具有很好的參考價值,下面就跟小編一起來看下吧
    2016-12-12
  • jQuery插件jRumble實現(xiàn)網(wǎng)頁元素抖動

    jQuery插件jRumble實現(xiàn)網(wǎng)頁元素抖動

    jRumble是jquery的插件,可以讓你選擇的元素抖動。 調(diào)用時只需一句代碼即可,有些抖動效果還挺可愛,可自定義的抖動效果,十分的炫酷,有需要的小伙伴可以參考下。
    2015-06-06
  • jQuery 插件開發(fā)指南

    jQuery 插件開發(fā)指南

    jQuery憑借其簡潔的API,對DOM強大的操控性,易擴展性越來越受到web開發(fā)人員的喜愛,經(jīng)常有人詢問一些技巧,因此干脆寫這么一篇文章給各位jQuery愛好者,算是拋磚引玉吧。
    2014-11-11
  • Expandable "Detail" Table Rows

    Expandable "Detail" Table Rows

    Expandable "Detail" Table Rows...
    2007-08-08
  • 基于jQuery實現(xiàn)的Ajax 驗證用戶名唯一性實例代碼

    基于jQuery實現(xiàn)的Ajax 驗證用戶名唯一性實例代碼

    本文分為jsp代碼和后臺代碼給大家介紹了基于jQuery實現(xiàn)的Ajax 驗證用戶名唯一性,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-06-06

最新評論

突泉县| 镇雄县| 道孚县| 门源| 高陵县| 东乡族自治县| 资兴市| 武清区| 新绛县| 清丰县| 贵阳市| 阳曲县| 安义县| 伊川县| 华宁县| 抚顺市| 民乐县| 开鲁县| 米脂县| 通化县| 阿尔山市| 公安县| 利津县| 库伦旗| 仙游县| 富民县| 万山特区| 五大连池市| 渭源县| 邵阳市| 峨眉山市| 九龙县| 易门县| 怀柔区| 伊宁市| 汶川县| 清徐县| 岱山县| 晋中市| 九寨沟县| 泰州市|