經常在寫程式碼的時候碰到這樣的場景:頁面初始化時顯示loading頁,同時啟動多個ajax並發請求獲取數據,當每個ajax請求返回時結束loading。
舉個例子,一個下訂單的頁面,要查詢常用地址資訊、商品資訊、地市資訊…而這些請求都是異步的,希望等到所有資料載入完成後再允許使用者操作。
要實現這個場景容易碰到的一個問題就是多並發怎麼控制?以下是一些解決方法和想法:
並行改為序列
如果業務邏輯本身是串列的,但是提供的請求方式又是異步的,可以考慮此方法。
但本場景顯然不是這種情況,這樣做大大降低了頁面效能,延長了載入速度。
回呼
只適合併發數少的情況,多層巢狀回呼會讓程式碼的可讀性大大降低
function async1(){ //do sth... } function async2(){ //do sth... async1(); } async2();
ajax改為同步
如在jquery中將async參數設定為false
$.ajax({ url:"/jquery/test1.txt", async:false });
設定結束標識
簡單一點的可以設定計數器,每完成一個非同步函數加1,或設定一個數組,每執行完一個非同步函數更新數組。
回呼計數
var cnt = 0; function async1(){ //do sth... callback(); } function async2(){ //do sth... callback(); } function callback(){ cnt++; if(2==cnt) console.log('都已执行完毕'); }
循環阻塞
var cnt = 0; function async1(){ //do sth... cnt++; } function async2(){ //do sth... cnt++; } while(2>cnt){}
循環非阻塞
不建議過度使用,以免影響效能
var cnt = 0; function async1(){ //do sth... cnt++; } function async2(){ //do sth... cnt++; } var interval = setInterval(function(){ if(2===cnt){ console.log('已执行完成'); clearInterval(interval) } }
第三方框架實作
jquery
目前我在專案中採用的方式
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 + '已完成'); });
以上內容是小編給大家介紹的關於JavaScript多並發問題如何處理的相關知識,希望對大家有幫助。