今天就跟大家聊聊有關(guān)使用Angular怎么實(shí)現(xiàn)異步變同步處理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
1. 背景
在前端項(xiàng)目中,經(jīng)常會(huì)遇到頁(yè)面有多個(gè)接口,后一個(gè)接口參數(shù)需要從前一個(gè)接口的返回?cái)?shù)據(jù)中獲取,這就存在接口必須按順序一個(gè)一個(gè)執(zhí)行。而Angular提供的Http服務(wù)請(qǐng)求接口都是異步請(qǐng)求,因此通常情況下會(huì)寫(xiě)成如下的代碼:
funA(arg1,arg2,function(){ funcB(arg1,arg2,function(){ funcC(arg1,arg2,function(){ xxxx.... }) }) });
這不僅造成頁(yè)面代碼混亂不易維護(hù),也讓開(kāi)發(fā)者無(wú)法追蹤代碼的運(yùn)行。本身嵌套就已經(jīng)不容易理解,加上不知何時(shí)才能觸發(fā)回調(diào),這就相當(dāng)于雪上加霜。
2. Promise
針對(duì)這中現(xiàn)象,Angular推出了Promise規(guī)范,它可以幫助開(kāi)發(fā)者將異步變成同步,是一種對(duì)執(zhí)行結(jié)果不確定的一種預(yù)先定義。例如以下代碼中,當(dāng)getData方法內(nèi)的對(duì)象成功執(zhí)行,就會(huì)調(diào)用success方法,如果失敗,就會(huì)調(diào)用error方法。另外promise除了then方法之外,還有catch()與finally()方法。
defer. getData() .then( funcSuccess (){}, funcError (){} ) .catch( function(){}) .finally( function(){});
Finally()方法一般用來(lái)處理不管promise是返回成功還是失敗,都會(huì)執(zhí)行的操作。例如ionic中的上拉加載,當(dāng)獲取數(shù)據(jù)后不管成功或者失敗,都要廣播結(jié)束這次上拉操作,便可將這個(gè)操作寫(xiě)在finally()方法中。
3. $q服務(wù)
q服務(wù)是AngularJs中自己封裝實(shí)現(xiàn)的一種Promise實(shí)現(xiàn),一般有如下三個(gè)常用方法:
defer() :創(chuàng)建一個(gè)deferred對(duì)象,這個(gè)對(duì)象可以執(zhí)行幾個(gè)常用的方法,比如resolve,reject,notify等;
all() :傳入Promise的數(shù)組,批量執(zhí)行,返回一個(gè)Promise對(duì)象;
when() :傳入一個(gè)不確定的參數(shù),如果符合Promise標(biāo)準(zhǔn),就返回一個(gè)Promise對(duì)象。
3.1. defer() 方法
在$q服務(wù)中,用defer()方法創(chuàng)建一個(gè)deferred對(duì)象,然后這個(gè)對(duì)象可以調(diào)用resolve方法定義成功狀態(tài),使用reject方法定義失敗狀態(tài),并且可以在這些方法中傳遞參數(shù),一般接口返回的數(shù)據(jù)都是用這些方法傳遞出去。最后通過(guò)deferred對(duì)象 .promise來(lái)返回一個(gè)promise對(duì)象,來(lái)定義then方法。then方法中有三個(gè)參數(shù),分別是成功回調(diào)、失敗回調(diào)、狀態(tài)變更回調(diào)。
定義方法:
function funA(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funA success'); }else{ defer.reject('funA error'); } return defer.promise; }
方法調(diào)用(返回成功):
funA(3).then(function(success){ console.log(success); },function(err){ console.log(err); })
結(jié)果:
方法調(diào)用(返回失敗):
funA(8).then(function(success){ console.log(success); },function(err){ console.log(err); })
結(jié)果:
3.2. 鏈?zhǔn)秸{(diào)用
了解了defer()方法與then()方法,接下來(lái)就能解決多個(gè)接口嵌套調(diào)用的問(wèn)題了。
一般處理多個(gè)接口需要嵌套執(zhí)行時(shí),可采用angular的鏈?zhǔn)秸{(diào)用,即:
FunA.then().then().then();
在then方法中return 要調(diào)用的下一個(gè)接口。如下funA、funB、funC都是返回了promise對(duì)象的方法,如果執(zhí)行順序?yàn)閒unA、funB、funC,則可用鏈?zhǔn)秸{(diào)用。
function funA(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funA success'); }else{ defer.reject('funA error'); } return defer.promise; } function funB(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funB success'); }else{ defer.reject('funB error'); } return defer.promise; } function funC(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funC success'); }else{ defer.reject('funC error'); } return defer.promise; }
方法調(diào)用:
funA(3).then(function(success){ console.log(success); return funB(3); }).then(function(success){ console.log(success); return funC(3); }).then(function(success){ console.log(success); },function(err){ console.log(err); });
結(jié)果:
上述方法調(diào)用中,then()方法中只寫(xiě)了成功參數(shù)的方法,如果其中一個(gè)方法調(diào)用返回失敗,則該方法后邊的方法都不會(huì)再執(zhí)行,也就是只有前一個(gè)方法調(diào)用成功,才能調(diào)用后邊的方法。如下為其中一個(gè)方法失敗的示例,funB方法調(diào)用返回失敗,則不會(huì)再執(zhí)行funC,而錯(cuò)誤的信息會(huì)在最后捕捉錯(cuò)誤信息的參數(shù)方法中獲取。
方法調(diào)用:
funA(3).then(function(success){ console.log(success); return funB(8); }).then(function(success){ console.log(success); return funC(3); }).then(function(success){ console.log(success); },function(err){ console.log(err); //打印funB()的錯(cuò)誤信息 });
結(jié)果:
如果在某些場(chǎng)景中,等前一個(gè)方法調(diào)用完畢,而不管這個(gè)方法是否調(diào)用成功,都要繼續(xù)調(diào)用后邊的方法,則需要在then()方法中增加錯(cuò)誤回調(diào)并return 下一個(gè)執(zhí)行的promise。如下:
funA(3).then(function(success){ console.log(success); return funB(8); },function(err){ console.log(err); return funB(8); }).then(function(success){ console.log(success); return funC(3); },function(err){ console.log(err); return funC(3); }).then(function(success){ console.log(success); },function(err){ console.log(err); });
結(jié)果:
3.3. all() 方法
all()方法可以把多個(gè)promise的數(shù)組合并成一個(gè)。當(dāng)所有的promise執(zhí)行成功后,會(huì)執(zhí)行后面的回調(diào),回調(diào)中的參數(shù),是每個(gè)promise執(zhí)行的結(jié)果。
function funA(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funA success'); }else{ defer.reject('funA error'); } return defer.promise; } function funB(num){ var defer = $q.defer(); if(num<5){ defer.resolve('funB success'); }else{ defer.reject('funB error'); } return defer.promise; }
方法調(diào)用:
$q.all([ funA(3), funB(3) ]) .then(function(success){ console.log(success); },function(err){ console.log(err); })
結(jié)果:
all() 方法中的參數(shù)可以是上面的數(shù)組形式,也可以是json格式。相應(yīng)的,如果參數(shù)是數(shù)組格式,那么返回的數(shù)據(jù)格式也是數(shù)組格式;如果參數(shù)是json格式,那么返回的數(shù)據(jù)格式也是json格式。json參數(shù)示例如下:
$q.all( { funA:DeferService.funA(3), funB:DeferService.funB(3) }) .then(function(success){ console.log(success); },function(err){ console.log(err); })
結(jié)果:
上面兩個(gè)示例展示的都是獲取數(shù)據(jù)成功的情況。而當(dāng)all()方法的參數(shù)中存在一個(gè)promise失敗,則整個(gè)任務(wù)都失敗,返回的數(shù)據(jù)也只會(huì)返回該失敗參數(shù)的失敗信息。
方法調(diào)用:
$q.all( { funA:DeferService.funA(8), //調(diào)用失敗 //正常情況下是調(diào)用成功,但由于funA調(diào)用失敗,固該方法也是失敗 funB:DeferService.funB(3) }) .then(function(success){ console.log(success); },function(err){ console.log(err); })
結(jié)果:
3.4. when() 方法
when()方法中的參數(shù)可以是一個(gè)值,也可以是一個(gè)promise,這個(gè)方法是把傳入的參數(shù)處理包裝成一個(gè)promise。這個(gè)方法一般在你不確定所處理的對(duì)象或者調(diào)用的方法是不是一個(gè)promise時(shí)使用。
例如在下面的例子中,val=10,并不是一個(gè)promise,但是經(jīng)過(guò)when()方法包裝之后,可以通過(guò).then()方法去調(diào)用,像處理平常的promise一樣。
var val=10; $q.when(val) .then(function(success){ console.log(success); },function(err){ console.log(err); });
結(jié)果:
看完上述內(nèi)容,你們對(duì)使用Angular怎么實(shí)現(xiàn)異步變同步處理有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
分享文章:使用Angular怎么實(shí)現(xiàn)異步變同步處理-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://aaarwkj.com/article36/jccsg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、企業(yè)建站、關(guān)鍵詞優(yōu)化、網(wǎng)站營(yíng)銷、營(yíng)銷型網(wǎng)站建設(shè)、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容