Ajax异步请求队列解决方案
使用Ajax请求一系列数据时,会因为异步请求无法判断返回值是那次请次的,而导致错误。
往往只能使用同步请求,而Ajax同步请求往往会锁定浏览器,甚至锁死。
解决方案是用异步请求队列,方案不是原创的,出自《JavaScript设计模式》一书。
发出来备忘,供大家参考。
var QueuedHandler = function(){ this.queue = []; // 请求队列 this.requestInProgress = false; // 判断当前是否己有别的请求 this.retryDelay = 5; // 设置每次重新请求的时间,单位为秒 }; QueuedHandler.prototype = { request:function(method,url,callback,postVars,override){ // 如果没有设置为覆盖模式,而且当前已经有别的请求 if(this.requestInProgress && !override){ this.queue.push({ method:method, url:url, callback:callback, postVars:postVars }); }else{ this.requestInProgress = true; var xhr = this.createXhrObject(); var that = this; xhr.onreadystatechange = function(){ if(xhr.readyState !== 4) return; if(xhr.status === 200){ callback.success(xhr.responseText,xhr.responseXML); // 判断请求队列是否为空,如果不为空继续下一个请求 that.advanceQueue(); }else{ callback.failure(xhr.status); // 每过一定时间重新请求 setTimeout(function(){ that.request(method,url,callback,postVars); },that.retryDelay * 1000); } }; xhr.open(method,url,true); if(method!=='POST')postVars = null; xhr.send(postVars); } }, createXhrObject:function(){ var methods = [ function(){return new XMLHttpRequest();}, function(){return new ActiveXObject('Msxml2.XMLHTTP');}, function(){return new ActiveXObject('Microsoft.XMLHTTP');}, ]; for(var i=0,len=methods.length;i<len;i++){ try{ methods[i](); }catch(e){ continue; } // this.createXhrObject = methods[i]; // return methods[i](); } throw new Error('SimpleHandler: Could not create an XHR object.'); }, advanceQueue:function(){ if(this.queue.length === 0){ this.requestInProgress = false; return; } var req = this.queue.shift(); this.request(req.method,req.url,req.callback,req.postVars,true); } };
调用方法:
var myHandler = new QueuedHandler(); var callback = { success:function(reponseText){alert(reponseText);}, failure:function(statusCode){alert(statusCode);} }; for (var i = 0; i < 5; i++) { t_url = "test.ashx?id="+i; myHandler.request("Get", t_url, callback); }
其中还能加入更多功能,比如从 QueuedHandler里反馈出来,正在处理第几个ajax请求;是否已经完成队列;强制停止ajax请求队列等等。