ajax队列
ajax高级程序设计上的。
/* * 将ajax根据优先级进行排列的方法 * 构造一个简单的排列函数,接受一个排序的函数 * 所有添加的ajax保存到_items中 * */ function PriorityQueue(fn){ this._items = []; if(typeof fn == 'function'){ this._compare = fn; } } PriorityQueue.prototype = { constructor:PriorityQueue, _compare:function(oValue1,oVlaue2){ if(oValue1<oVlaue2){ return -1; }else if(oValue1 > oVlaue2){ return 1; }else{ return 0; } }, //排序 prioritze:function(){ this._items.sort(this._compare) }, //移除并返回第一个ajax get:function(){ return this._items.shift(); }, //返回对列中指定的ajax item:function(iPos){ return this._items[iPos]; }, //返回队列中第一个ajax peek:function(){ return this._items[0]; }, //将一个ajax插入到队列中,并排序 put:function(oValue){ this._items.push(oValue); this.prioritze(); }, //返回队列的长度 size:function(){ return this._items.length; }, //移除一个指定的ajax,成功后返回true,否则false remove:function(oValue){ for(var i=0,len=this._items.length;i<len;i++){ if(this._items[i] == oValue){ this._items.splice(i,1); return true; } }; return false; } } /* * * */ var RequestManager = (function(){ var oManager = { //队列是最长等待时间 AGE_LIMIT:60000, //默认优先级10 DEFAULT_PRIORTY:10, //检查队列时间间隔 INTERVAL:250, //保存正在执行的ajax _active:[], //队列实例 _pending:new PriorityQueue(function(oRequest1,oRequest2){ return oRequest1.priority - oRequest2.priority; }), //检查每个ajax的等待时间,如果超出默认的最长时间,则提高该ajax的优先级 _agePromote:function(){ for(var i=0;i<this._pending.size();i++){ var oRequest = this._pending._items[i]; oRequest.age += this.INTERVAL; if(oRequest.age >= this.AGE_LIMIT){ oRequest.age = 0; oRequest.priority--; }; }; this._pending.prioritze(); }, //检查正在执行的ajax状态, _checkActiveRequests:function(){ var oRequest = null; var oTransport = null; for(var i=this._active.length-1; i>=0; i--){ oRequest = this._active[i]; oTransport = oRequest.transport; if(oTransport.readyState == 4){ oRequest.active = false; this._active.splice(i,1); var fnCallback = null; if(oTransport.status >= 200 && oTransport.status < 300){ if(typeof oRequest.onsuccess == 'function'){ fnCallback = oRequest.onsuccess; } }else if(oTransport.status == 304){ if(typeof oRequest.onnotmodified == 'function'){ fnCallback = oRequest.onnotmodified; } }else{ if(typeof oRequest.onfailure == 'function'){ fnCallback = oRequest.onfailure; } } if(fnCallback != null){ setTimeout((function(fnCallback,oRequest,oTransport){ return function(){ fnCallback.call(oRequest.scope||window, { status : oTransport.status, data : oTransport.responseText, request : oRequest }) } })(fnCallback,oRequest,oTransport),1); } } } }, //封装XMLHttpRequest _createTransprot:function(){ if(typeof XMLHttpRequest != 'undefined'){ return new XMLHttpRequest(); }else if(typeof ActiveXObject != 'undefined'){ var xhr = null; try{ xhr = new ActiveXObject('MSXML2.XmlHttp.6.0'); return xhr; }catch(e){ try{ xhr = new ActiveXObject('MSXML2.XmlHttp.3.0'); return xhr; }catch(e){ throw Error('cannot create XMLHttp object!'); } } } }, //发送一下个请求,检查当前执行的ajax是否小于2,如果是,则激活下一个ajax _sendNext:function(){ if(this._active.length <2){ var oRequest = this._pending.get(); if(oRequest != null){ this._active.push(oRequest); oRequest.transport = this._createTransprot(); oRequest.transport.open(oRequest.type,oRequest.url,true); oRequest.transport.send(oRequest.data); oRequest.active = true; } } }, //取消指定的ajax,如果有回调函数oncancel,则执行 cancel:function(oRequest){ if(!this._pending.remove(oRequest)){ oRequest.transport.abort(); if(this._active[0] === oRequest){ this._active.shift(); }else if(this._active[1] === oRequest){ this._active.pop(); }; if(typeof oRequest.oncancel == 'function'){ oRequest.oncancel.call(oRequest.scope||window,{request:oRequest}) } } }, //添加一个ajax到队列中 send:function(oRequest){ if(typeof oRequest.priority != 'number'){ oRequest.priority = this.DEFAULT_PRIORTY; }; oRequest.active = false; oRequest.age = 0; this._pending.put(oRequest); }, /* * 预置一些方面,方便不知道该如何设置优先的情况 * 其实也就是给这些方法加了个默认的优先级 */ poll:function(oRequest){ oRequest.priority = 3; this.send(oRequest); }, prefetch:function(oRequest){ oRequest.priority = 5; this.send(oRequest); }, submit:function(oRequest){ oRequest.priority = 0; this.send(oRequest); }, submitPart:function(oRequest){ oRequest.priority = 2; this.send(oRequest); }, }; //通过setInterval,不断的检查队列中ajax执行情况, //如果执行完,添加下一个 //如果超过最长等待时间,则提高优先级 //据说这里之所以不用onreadystatechange是为了避免IE下的内存问题 //但感觉这样在页面上不停的setinterval,同样让人蛋疼啊! setInterval(function(){ RequestManager._checkActiveRequests(); RequestManager._sendNext(); RequestManager._agePromote(); },oManager.INTERVAL); return oManager; })(); /* 用法: RequestManager.send({ priority:0, type:'get', url:'data.txt', onsuccess:function(){}, onfailure:function(){}, onnotmodified:function(){} }) */