以jQuery中$.Deferred對(duì)象為例講解promise對(duì)象是如何處理異步問(wèn)題
Promises是一種令代碼異步行為更加優(yōu)雅的抽象,它很有可能是JavaScript的下一個(gè)編程范式,一個(gè)Promise即表示任務(wù)結(jié)果,無(wú)論該任務(wù)是否完成。
在一些現(xiàn)代瀏覽器中已經(jīng)提供了原生的Promise對(duì)象,其遵循Promise/A+標(biāo)準(zhǔn)。在jQuery1.5+,提供了$.Deferred(其可以被轉(zhuǎn)化為promise對(duì)象)。很多知名的框架中,也提供了promise對(duì)象。promise對(duì)象在javascript中已經(jīng)是一種很重要的模式,它在解決異步問(wèn)題時(shí)表現(xiàn)出的優(yōu)雅,正是javascript所需要的。以下以jQuery中的$.Deferred對(duì)象為例,來(lái)看一下promise對(duì)象是如何處理異步問(wèn)題。關(guān)于$.Deferred對(duì)象,可以到j(luò)Query官網(wǎng)查看,這里就不贅述了。
一、封裝異步操作
首先,我們以加載圖片為例,看以下代碼:
//加載圖片函數(shù)
var loadImg = function(url){
var img = new Image() , deferred = $.Deferred() ;
img.src = url ;
img.onload = function(){
//成功則觸發(fā)deferred.resolve
deferred.resolve( this ) ;
} ;
img.onerror = function(e){
//失敗則觸發(fā)deferred.reject
deferred.reject( e );
} ;
//返回promise對(duì)象
return deferred.promise() ;
} ;
//請(qǐng)求圖片
var request = loadImg('http://r2.ykimg.com/0515000054AFFC2D6737B343930AFAD6') ;
//請(qǐng)求成功
request.done(function(img){
//code
}) ;
//可以注冊(cè)多個(gè)回調(diào),當(dāng)請(qǐng)求成功時(shí),會(huì)按注冊(cè)的順序執(zhí)行,fail和always也有此性質(zhì)
request.done(function(img){
// code
});
//請(qǐng)求失敗
request.fail(function(){
// code
}) ;
//請(qǐng)求完畢
request.always(function(){
//code
});
以上的代碼,我封裝了圖片加載的操作,將他們委托給$.Deferred,最后生成一個(gè)promise返回。使用這樣的方式,相比用對(duì)外暴露回調(diào)的方式,顯得更干凈、更清晰。這么做的另一個(gè)更重要的原因是,promise的連接。
二、promise的連接
我們還是以上面圖片加載的代碼為例,來(lái)看一下如何做promise的連接,看以下代碼:
var request = loadImg('http://b1.hucdn.com/upload/item/1411/13/89613257775992_800x800.jpg') ;
request.done(function(img){
//code
}) ;
//request連接別的promise之后返回的promise
var request3 = request.then(function(img){
//request執(zhí)行成功時(shí) 連接request1
var request1 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;
return request1 ;
},function(e){
//request執(zhí)行失敗時(shí) 連接request2
var request2 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;
return request2 ;
});
//request執(zhí)行并且request1或request2成功執(zhí)行時(shí)
request3.done(function(done){
//code
}) ;
promise對(duì)象提供了then的方法,它接受兩個(gè)回調(diào):onResolve和onReject,在回調(diào)中返回promise,就可以完成promise之間的連接。通過(guò)這種方式,可以使異步操作串行的執(zhí)行。
同時(shí),jQuery還提供了另外一種連接方式,看代碼:
var request = loadImg('http://b1.hucdn.com/upload/item/1412/23/48188827139381_800x800.jpg') ;
var request1 = loadImg('http://b1.hucdn.com/upload/item/1412/06/50258594673502_800x800.jpg') ;
//通過(guò)$.when連接promise
var request2 = $.when(request,request1) ;
request2.done(function(img,img){
//code
}) ;
jQuery中提供了$.when這個(gè)函數(shù),它可以接受n個(gè)promise對(duì)象為參數(shù),它是將promise的執(zhí)行結(jié)果連接在一起。使用這種方式,多個(gè)異步操作可以并行執(zhí)行。
三、The End
這里的代碼是以加載圖片為例,同樣的做法可以應(yīng)用到其他的異步操作中去。比如jQuery中的$.ajax、$.fn.animate,調(diào)用它們返回的就是promise。在node端,也可以把一些異步操作(讀數(shù)據(jù)庫(kù)、讀文件等)封裝成promise。繼而對(duì)多個(gè)promise實(shí)現(xiàn)合并的操作,使其串行或者并行執(zhí)行。
附:deferred對(duì)象
deferred除了用于轉(zhuǎn)化promise對(duì)象外,本身也是個(gè)很有用的對(duì)象。它除了提供像promise對(duì)象的那些方法和屬性外,還有notify函數(shù)和progress函數(shù),這兩個(gè)函數(shù)在實(shí)現(xiàn)進(jìn)度條和瀑布流的時(shí)候,有很大的用處。
在實(shí)現(xiàn)進(jìn)度條時(shí),resolve和done函數(shù)可以用于定義進(jìn)度條讀取到100%時(shí)的觸發(fā)時(shí)機(jī)和觸發(fā)邏輯,notify和progress函數(shù)可以用于定義進(jìn)度條在讀取中的觸發(fā)時(shí)機(jī)和觸發(fā)邏輯。reject和fail函數(shù)可以用于定義進(jìn)度讀取失敗時(shí)的觸發(fā)時(shí)機(jī)和觸發(fā)邏輯。
在實(shí)現(xiàn)瀑布流時(shí),resolve和done函數(shù)可以用于定義當(dāng)數(shù)據(jù)已經(jīng)全部加載到頁(yè)面的觸發(fā)時(shí)機(jī)和觸發(fā)邏輯,notify和progress函數(shù)可以用于定義瀑布流讀取下一頁(yè)的觸發(fā)時(shí)機(jī)和觸發(fā)邏輯。
- jQuery Ajax異步處理Json數(shù)據(jù)詳解
- 詳談 Jquery Ajax異步處理Json數(shù)據(jù).
- jQuery的deferred對(duì)象使用詳解
- 利用jQuery的deferred對(duì)象實(shí)現(xiàn)異步按順序加載JS文件
- jQuery.deferred對(duì)象使用詳解
- jQuery通過(guò)deferred對(duì)象管理ajax異步
- jQuery的promise與deferred對(duì)象在異步回調(diào)中的作用
- jQuery中deferred對(duì)象使用方法詳解
- jQuery的deferred對(duì)象詳解
- javascript異步處理與Jquery deferred對(duì)象用法總結(jié)
相關(guān)文章
jQuery EasyUI ProgressBar進(jìn)度條組件
這篇文章主要為大家詳細(xì)介紹了jQuery EasyUI ProgressBar進(jìn)度條組件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
jQuery基于ajax實(shí)現(xiàn)星星評(píng)論代碼
這篇文章主要介紹了jQuery基于ajax實(shí)現(xiàn)星星評(píng)論代碼,可實(shí)現(xiàn)實(shí)時(shí)顯示評(píng)論效果的功能,基于Ajax實(shí)現(xiàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-08-08
解決jquery操作checkbox火狐下第二次無(wú)法勾選問(wèn)題
在工作中使用jquery操作checkbox,進(jìn)行全選、反選,現(xiàn)在的問(wèn)題是火狐下第二次無(wú)法勾選問(wèn)題,在下面有個(gè)詳細(xì)的解答,感興趣的朋友可以參考下2014-02-02
jquery如何判斷表格同一列不同行input數(shù)據(jù)是否重復(fù)
這篇文章主要介紹了jquery如何判斷表格同一列不同行input數(shù)據(jù)是否重復(fù),需要的朋友可以參考下2014-05-05
Jquery 一次處理多個(gè)ajax請(qǐng)求的代碼
Jquery 一次處理多個(gè)ajax請(qǐng)求的代碼,需要的朋友可以參考下。2011-09-09
firefox下jquery iframe刷新頁(yè)面提示會(huì)導(dǎo)致重復(fù)之前動(dòng)作
刷新頁(yè)面會(huì)提示要顯示此頁(yè)面, Firefox 必須發(fā)送將會(huì)導(dǎo)致重復(fù)之前動(dòng)作的數(shù)據(jù),此問(wèn)題很是疑惑,接下來(lái)將為您解答,需要的朋友可以了解下2012-12-12
基于JQuery和DWR實(shí)現(xiàn)異步數(shù)據(jù)傳遞
這篇文章主要介紹了基于JQuery和DWR實(shí)現(xiàn)異步數(shù)據(jù)傳遞,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10

