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

	})

*/

  

你可能感兴趣的:(Ajax)