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(){}
})
*/