最近項(xiàng)目中遇到了一個(gè)功能,會涉及到不少并發(fā)的請求,但是公司瀏覽器又不支持Promise母剥、async/await,正好趁此機(jī)會總結(jié)一下有關(guān)異步請求的處理方式形导。
簡化下項(xiàng)目中實(shí)際遇到的問題环疼,去掉其他的邏輯:
有一個(gè)最終包含n個(gè)子節(jié)點(diǎn)的xml對象
<rules>
<rule1>....</rule1>
<rule2>....</rule2>
<rule3>....</rule3>
.....
<rulen>....</rulen>
</rules>
需要遍歷每個(gè)子節(jié)點(diǎn),每次遍歷到這個(gè)節(jié)點(diǎn)的時(shí)候朵耕,利用包括這個(gè)節(jié)點(diǎn)以及其prev的節(jié)點(diǎn)作為一個(gè)xml規(guī)則炫隶,去異步請求,最終拿到所有異步的結(jié)果去進(jìn)行下面的邏輯阎曹。
再簡化下伪阶,
遍歷一個(gè)數(shù)組煞檩,拿每一項(xiàng)作為參數(shù)去異步請求
var arr = [1,2,3,4,5,6,7,8,9];
需求:因?yàn)镴S事件循環(huán)的機(jī)制,后續(xù)執(zhí)行的同步代碼的需要之前所有異步操作的結(jié)果
方案一:并行改串行
最簡單的方法就是用回調(diào)栅贴,將每次的異步操作分別放到之前異步的回調(diào)里:
function async1(){
async2()
}
function async2(){
//....
}
async1();
優(yōu)點(diǎn):簡單
缺點(diǎn):總執(zhí)行時(shí)間是所有異步請求累加斟湃,可能會很長
方案二:用一個(gè)變量來計(jì)數(shù)
function async1(){
callback()
}
function async2(){
callback()
}
function callback(){
cnt++
if(2==cnt){
console.log('都執(zhí)行完畢')
}
}
方案三:在方案二中不用回調(diào)計(jì)數(shù),用定時(shí)器計(jì)數(shù)
var cnt = 0;
function async1(){
cnt++
}
function async2(){
cnt++
}
var interval = setInterval(function(){
if(cnt==2){
console.log("執(zhí)行完畢")
clearInterval(interval);
}
})
缺點(diǎn):定時(shí)器占用CPU較多
方案四:jquery的Deferred
var d1 = $.Deferred();
var d2 = $.Deferred();
function async1(){
d1.resolve( "Fish" );
}
function async2(){
d2.resolve( "Pizza" );
}
$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 + v2 + '已完成');
});