摘要:三和對象方法對象其實就是對象的特例,因為對象不能更改異步狀態(tài),而對象可以。方法依次接受三個回調(diào),分別為對象后觸發(fā)的回調(diào),返回一個對象。注意,必須傳入函數(shù),而該函數(shù)只有返回一個對象,才能夠讓異步事件按照預期順序來執(zhí)行。對象的方法對象和對象
一、前言
為了讓前端們從回調(diào)的地獄中回到天堂,jQuery也引入了Promise的概念。Promise是一種令代碼異步行為更加優(yōu)雅的抽象,有了它,我們就可以像寫同步代碼一樣去寫異步代碼。jQuery從1.5版本開始實現(xiàn)了CommonJS Promise/A規(guī)范這一重量級方案,不過沒有嚴格按照規(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對象可以。這點在他們的方法設計上,有著明顯的體現(xiàn)。
1.promise對象方法通常,對于DOM,動畫,ajax相關(guān)方法,我們都可以使用Promise方法。調(diào)用Promise方法,返回的是Promise對象。可以鏈式調(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("請求錯誤"); });
動畫示例已有,就不重復列出了。
2.deferred對象方法對于deferred對象呢,也就是使用$.Deferred()方法,以及$.when()等方法創(chuàng)造出來的對象,有如下的常用方法:
resolve,reject,notify;
done,fail,progress;
另外還有promise、then和always方法。
之所以這么排版,是因為他們是對應的,也就是說: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對象放在了wait函數(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對象,才能夠讓異步事件按照預期順序來執(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也是一樣的。
四、參考文章因為jQuery deffered和promise對象方法使用起來比較繁瑣,接口太多,同樣一件事兒,你可以有好幾種寫法。所以,某些接口方法可能會被廢棄。若要使用其它方法,請去官網(wǎng)參考。
jQuery deferred 對象的 promise 方法
Promise對象和Deferred對象
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78168.html
摘要:和異步處理調(diào)用訪問數(shù)據(jù)采用的方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調(diào),其實這兩種處理方式實現(xiàn)原理差不多,都需要在調(diào)用異步過程的時候傳入一個在異步過程結(jié)束的時候調(diào)用的接口。 Ajax 和異步處理 調(diào)用 API 訪問數(shù)據(jù)采用的 Ajax 方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調(diào),其實這兩種處理方式實現(xiàn)原理差不多,都需要在調(diào)用異步過程的時候傳入一個在異...
摘要:和和都有和,但是略有不同。實際上返回的是一個對象。和添加的回調(diào),添加的回調(diào)。所以在調(diào)用成功的情況下執(zhí)行添加的回調(diào),調(diào)用失敗時執(zhí)行添加的回調(diào)。,產(chǎn)生對象并,產(chǎn)生對象并,然后繼續(xù)處理,的語法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不過它們的作用可以簡單的用兩句話來描述 Deffere...
摘要:依次循環(huán)直到當前沒有子如何讓異步的在函數(shù)中拿到將函數(shù)和放入同一個對象對象里面的時候?qū)⒃O置。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果。就算改變已經(jīng)發(fā)生了,你再對對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果。 let promise = new Promise((resolve111, reject) => { //這里放入我們要執(zhí)行的函數(shù),可能是同步,也可能是異...
原文鏈接:鏈接 1 最簡單一個案例 function runAsync(){ let p = new Promise(function(resolve,reject){ console.log(exec); setTimeout(function(){ resolve(someData); },2000); }); return p; } var ...
摘要:而同步和異步則是描述另一個方面。異步將數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間的操作由系統(tǒng)自動處理,然后通知應用程序直接使用數(shù)據(jù)即可。 前言 ?上周5在公司作了關(guān)于JS異步編程模型的技術(shù)分享,可能是內(nèi)容太干的緣故吧,最后從大家的表情看出這條粉腸到底在說啥?的結(jié)果:(下面是PPT的講義,具體的PPT和示例代碼在https://github.com/fsjohnhuan...上,有興趣就上去看看吧! ...
閱讀 1118·2021-11-23 09:51
閱讀 1081·2021-10-18 13:31
閱讀 2991·2021-09-22 16:06
閱讀 4284·2021-09-10 11:19
閱讀 2206·2019-08-29 17:04
閱讀 437·2019-08-29 10:55
閱讀 2485·2019-08-26 16:37
閱讀 3381·2019-08-26 13:29