此篇要分享的是大量並發AJAX請求的情況,對於單獨的請求,其實沒什么意義,doc上面就可以找到很多sample.
場景: 有n條請求需要發送給后台,單次請求的時間不定。
分析: 如果把n條都放在一次請求里面,會遇到2個問題。
1. 請求數據庫時間太長,timeout.
2. 頁面時間太長,timeout.
3. 發送內容太大,頁面掛
比較靠譜的方案是負載均衡,將請求切割以使每次請求的內容和時間都能保證在合理的范圍。同時加上遮罩,可以及時刷新進度。
直接貼關鍵代碼部分。
1 requestWaferDies: function(LOTS, step, root){ 2 var output = MyApp.settings['WaferDieOutput'].getOutputs(); 3 if(!(wafer_store.hasOwnProperty('unit'))){wafer_store.unit = {}} 4 var lots = LOTS.split(',').filter(function(w){if(!(wafer_store.unit.hasOwnProperty(w))){return true}}); 5 if(lots.length > 0){ 6 var size_of_request = 1; 7 var paras = {lot:lots, step: step, output:output}; 8 wafer_store.progress = []; 9 this.PB_percentage(lots.length, root, LOTS); 10 this.req_fn1(paras, size_of_request); 11 } 12 },
這部分主要做負載均衡,把任務切割,並配發任務。
1 PB_percentage: function(lot_len, root, LOTS) { 2 var progressBar=Ext.Msg.show({ 3 title:"", 4 msg:"Loading data .....", 5 progress:true, 6 width:300 7 }); 8 var count=0; 9 var bartext=""; 10 var curnum=0; 11 var me = this; 12 13 var task = { 14 run:function () { 15 count = wafer_store.progress.length; 16 if (count>lot_len) { 17 progressBar.hide(); 18 Ext.TaskManager.stop(task); 19 wafer_store.progress = []; //reset 20 arguments[0].plot_heatmap(root,arguments[1]); 21 } 22 curnum=count/lot_len; 23 bartext=parseInt(curnum*100)+"%"; 24 progressBar.updateProgress(curnum,bartext); 25 if (count==lot_len) { //to show 100% 26 wafer_store.progress.push('any'); 27 } 28 }, 29 args:[me, LOTS], 30 interval:100 31 } 32 Ext.TaskManager.start(task); 33 34 },
首先生成遮罩,然后定時刷新,判斷是否需要更新狀態和結束遮罩。注意參數傳遞方式。
1 req_fn1: function(paras, size){ // to request unit level data per wafer# && step 2 var res = {}; 3 Ext.Ajax.request({ 4 url: 'backend/api/Data/query_wafer_dies_per_lot_oper', 5 method: 'POST', 6 async: true, 7 headers: { 'Content-Type': 'application/json'}, 8 jsonData : { 9 lot_name: paras.lot.slice(0, size), 10 step: paras.step, 11 outputs: paras.output, 12 }, 13 // timeout: 60000, 14 scope: this, 15 success: function(responseTxt){ 16 // this.sessionExpireMessage(responseTxt); 17 JSON.parse(responseTxt.responseText).data.map(function(d){ 18 if(res.hasOwnProperty(d.lot_number)){ 19 res[d.lot_number].push(d); 20 }else{ 21 res[d.lot_number] = [d]; 22 } 23 }) 24 Object.getOwnPropertyNames(res).map(function(lot){ 25 if(!wafer_store.unit.hasOwnProperty(lot)){ 26 wafer_store.unit[lot] = res[lot]; 27 wafer_store.progress.push(lot); 28 // console.log(wafer_store.unit[lot].length); 29 } 30 }) 31 32 if(paras.lot.slice(size,999999).length > 0){ 33 paras.lot = paras.lot.slice(size,999999); 34 this.req_fn1(paras, size); 35 } 36 }, 37 failure: function(response){alert('server-side failure with status code ' + response.status + '\nrefresh your page and try again.')}//this.serverFailRequest 38 }); 39 },
數據請求部分,注意,異步,並且在callback里面調用下一次AJAX.否則不行。
好了,最后的效果,如下圖,個人覺得還是很完美的。