进度条在AJAX请求中的应用
此篇要分享的是大量并发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.否则不行。
好了,最后的效果,如下图,个人觉得还是很完美的。