摘要:三和對象方法對象其實就是對象的特例,因為對象不能更改異步狀態,而對象可以。方法依次接受三個回調,分別為對象后觸發的回調,返回一個對象。注意,必須傳入函數,而該函數只有返回一個對象,才能夠讓異步事件按照預期順序來執行。對象的方法對象和對象
一、前言
為了讓前端們從回調的地獄中回到天堂,jQuery也引入了Promise的概念。Promise是一種令代碼異步行為更加優雅的抽象,有了它,我們就可以像寫同步代碼一樣去寫異步代碼。jQuery從1.5版本開始實現了CommonJS Promise/A規范這一重量級方案,不過沒有嚴格按照規范進行實現,有一些API上的差異。
好,讓我們來看看他們的特性吧(本文示例基于jQuery 1.8版本以上)。
二、示例以前寫動畫時,我們通常是這么干的:
$(".animateEle").animate({ opacity:".5" }, 4000,function(){ $(".animateEle2").animate({ width:"100px" },2000,function(){ // 這樣太傷了 $(".animateEle3").animate({ height:"0" },2000); }); });
假如這么使用回調的話,那就太傷了。幸好,還有一些現成的Promise解決方案來優雅地解決這種問題。
我們看看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);
很明顯,更改后的代碼更易懂易讀了。
但是,上面的代碼,有些細節的東西并沒有透露,一不小心,就容易出錯,得不到我們想要的順序完成動畫的效果。下面讓我們來全面理解jQuery提供的Promise和deferred對象的方法,看看到底如何使用。
三、promise和deffered對象方法Promise對象其實就是deferred對象的特例,因為Promise對象不能更改異步狀態,而deferred對象可以。這點在他們的方法設計上,有著明顯的體現。
1.promise對象方法通常,對于DOM,動畫,ajax相關方法,我們都可以使用Promise方法。調用Promise方法,返回的是Promise對象。可以鏈式調用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對象,所以可以不必顯式調用Promise方法):
$.post("/",{}).done(function(data){ console.log("請求成功"); }).fail(function(){ console.log("請求錯誤"); });
動畫示例已有,就不重復列出了。
2.deferred對象方法對于deferred對象呢,也就是使用$.Deferred()方法,以及$.when()等方法創造出來的對象,有如下的常用方法:
resolve,reject,notify;
done,fail,progress;
另外還有promise、then和always方法。
之所以這么排版,是因為他們是對應的,也就是說:resolve方法會觸發done的回調執行,reject會觸發fail的回調,notify會觸發progress的回調。
直接看代碼:
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函數中,返回的是個Promise對象,而不是deferred對象。
要知道,Promise對象是沒有resolve,reject,notify等方法的,也就意味著,你無法針對Promise對象進行狀態更改,只能在done或fail中進行回調配置。所以,你如果這么調用wait(2500).resolve()將會報錯,因為wait(2500)返回的是個Promise對象,不存在resolve方法。
但是,這么做,有個好處,我們把dtd這個deferred對象放在了wait函數中,作為了局部變量,避免了全局的污染;進一步通過Promise方法,轉化dtd這個deferred對象為Promise對象,避免了函數wait外部可能發生的狀態更改(假如我們確實有這個需求)。
比如:
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對象的狀態,這樣必然觸發該對象的fail回調函數。
對于always方法,從字面意思上就很容易理解,deferred對象無論是resolve還是reject,都會觸發該方法的回調。
3.其它共性此處講講then和$.when方法的使用。它們對Promise對象也適用。
$.when方法接受多個deferred對象或者純javascript對象,返回Promise對象。
then方法依次接受三個回調,分別為deferred對象resolve,reject,notify后觸發的回調,返回一個Promise對象。注意,必須傳入函數,而該函數只有返回一個Promise對象,才能夠讓異步事件按照預期順序來執行。
我們來看看最開始的動畫示例代碼,$.when(animate1()).then(animate2).then(animate3),$.when方法中接受了一個animate1的函數執行結果,也就是得到了一個Promise對象,而后的then中,則只是接受了一個變量名,這樣得到的結果是一個匿名的函數體,而該函數中返回的是Promise對象。正好符合了我們對then接受參數的要求。
假如我們把執行語句改成:$.when(animate1()).then(animate2()).then(animate3()),這樣造成的結果就是三個動畫同步執行了。與$.when(animate1(),animate2(),animate3())無異。
既然then是如此要求,那么與then方法類似的done,fail,progress也是一樣的。
四、參考文章因為jQuery deffered和promise對象方法使用起來比較繁瑣,接口太多,同樣一件事兒,你可以有好幾種寫法。所以,某些接口方法可能會被廢棄。若要使用其它方法,請去官網參考。
jQuery deferred 對象的 promise 方法
Promise對象和Deferred對象
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78168.html
摘要:和異步處理調用訪問數據采用的方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異步過程結束的時候調用的接口。 Ajax 和異步處理 調用 API 訪問數據采用的 Ajax 方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異...
摘要:和和都有和,但是略有不同。實際上返回的是一個對象。和添加的回調,添加的回調。所以在調用成功的情況下執行添加的回調,調用失敗時執行添加的回調。,產生對象并,產生對象并,然后繼續處理,的語法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不過它們的作用可以簡單的用兩句話來描述 Deffere...
摘要:依次循環直到當前沒有子如何讓異步的在函數中拿到將函數和放入同一個對象對象里面的時候將設置。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對對象添加回調函數,也會立即得到這個結果。 let promise = new Promise((resolve111, reject) => { //這里放入我們要執行的函數,可能是同步,也可能是異...
原文鏈接:鏈接 1 最簡單一個案例 function runAsync(){ let p = new Promise(function(resolve,reject){ console.log(exec); setTimeout(function(){ resolve(someData); },2000); }); return p; } var ...
摘要:而同步和異步則是描述另一個方面。異步將數據從內核空間拷貝到用戶空間的操作由系統自動處理,然后通知應用程序直接使用數據即可。 前言 ?上周5在公司作了關于JS異步編程模型的技術分享,可能是內容太干的緣故吧,最后從大家的表情看出這條粉腸到底在說啥?的結果:(下面是PPT的講義,具體的PPT和示例代碼在https://github.com/fsjohnhuan...上,有興趣就上去看看吧! ...
閱讀 1107·2021-11-23 09:51
閱讀 1074·2021-10-18 13:31
閱讀 2967·2021-09-22 16:06
閱讀 4256·2021-09-10 11:19
閱讀 2196·2019-08-29 17:04
閱讀 425·2019-08-29 10:55
閱讀 2472·2019-08-26 16:37
閱讀 3369·2019-08-26 13:29