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

  

posted @ 2011-11-30 15:48  zjhsd2007  阅读(1315)  评论(0编辑  收藏  举报