Ajax事件队列,降低并发请求对服务器的压力


/*******************-------------注释掉的是通过types来判断是否是轮训的请求,如果是types==1,那么则是由注册机----------
********************-------------自动判断下次的执行,如果超过时间过久,那么可以再添加Settimeout再起启动当前-----------
********************--------------的请求,如果外部设置定时器,则按照正常顺序执行!------------------------------------************/
function AjaxQueue(){
	var queue = []
		,that = this;
	this.queue = [];
	this.urlArr = [];
	this.update = function(){
		var length = that.queue.length,key;
        if(length<5){
            key = length-1;
        }
        if(that.queue[length-1].post){
                return;
        }
		that.queue[key||4].go(length-1);
		return that.queue[key||4];
	}
	this.XHR = function(method,url,func,types){
		if(that.urlArr.indexOf(this.arr)){
			return null;
		}
		var that_that =this;
		this.types = types;//轮训机制(如果传递参数没变化可以,如果变化就不好用)
		this.method = method;
		this.url =url;
		this.func =func;
		this.post = false;
		this.go =function(i){
			var ajax = new XMLHttpRequest()//兼容性不考虑(IE ActiveXObject(Mcrosoft.XMLHTTP))
			//ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//(post)
			ajax.open(that_that.method,that_that.url,true);
			ajax.onreadystatechange=that_that.func;
			ajax.onerror = function(){};
			ajax.onloadend=function(){
				that.queue.splice(i,i+1);
				that.urlArr.splice(i,i+1);
				/* if(that_that.types){
					setTimeout(function(){
						that.queue.push(that_that);
						that.update();
					},types*1000);
					return false;
				} */
				that_that = null;
			}
			ajax.send();
			that_that.post = true;
		}
		that.urlArr.push(this.arr);
		that.queue.push(this);
		that.update();
	}	
}

 另一种机制,不断监听队列

/**
 * 定时调度安装
 * 
 * 使用方式说明:
 * 
 * new Polling();
 * 
 */
(function(Polling) {
	if (typeof define === 'function' && define.amd) {
		define([], Polling);
	}
})(function() {
	// 1、定义类名
	var CLASS_NAME = "Polling";
	var polling_install = function(GS) {
		{// 防止重复安装
			if (!!GS[CLASS_NAME]) {
				return GS[CLASS_NAME];
			}
		}
		// 2、定义类构造函数
		var CLASS_CONSTRUCTOR = function(param) {
			if (typeof param == 'function') {
				this.success = param;
			} else {
				Object.assign(this, param);// id,url,data,success,seconds
			}
			this.bindDom = f.$MainCtr().children()[0];// 用于默认enable逻辑
			this.id = this.id || GS[CLASS_NAME].__static.id(this);
			GS[CLASS_NAME].instances[this.id] = this;
			this.execute();
		};
		// 3、安装类:将[定时调度]安装在[GS]上
		GS[CLASS_NAME] = CLASS_CONSTRUCTOR;
		// 4、定义类的一般成员属性<通过prototype>
		Object.assign(GS[CLASS_NAME].prototype, {
			seconds : 5,// 默认的轮询周期:5秒
			// 4.1、执行异步任务
			execute : function() {
				if (this.isWaiting || !this.fnv(this.enable)) {// 等待中或不可用,则跳过
					return;
				}
				var that = this;
				var url = this.fnv(this.url);
				var executeSuccess = function() {
					if (that.fnv(that.enable())) {
						that.success.apply(this, arguments);
					}
				};
				if (!url) {
					executeSuccess();
				} else {
					this.isWaiting = true;
					f.postData({
						showMessage : false,
						url : url,
						data : this.fnv(this.data),
						success : executeSuccess,
						error : f.emptyFunc,
						complete : function() {
							that.isWaiting = false;
						}
					});
				}
			},
			// 4.2、任务失效,默认[父元素不存在则视为页面已经跳转,此定时器已不可用]
			enable : function() {
				return !!this.bindDom.parentNode;
			},
			// 4.2、任务销毁,默认[定时器不可用时则销毁]
			distroy : function() {
				return !this.fnv(this.enable);
			},
			// 函数则返回执行结果、否则直接返回
			fnv : function(o) {
				return typeof o == "function" ? o.call(this) : o;
			}
		});
		// 5、定义静态函数和常量
		GS[CLASS_NAME].__static = new function() {
			// 轮询频率
			this.TIME_CLOCK = 1000;
			// 最大计数
			this.MAX_INTERVAL_COUNT = 1000;
			// 作用:如果轮询对象没有ID,则默认给定一个随机数ID
			this.id = function(polling) {
				return "P" + f.random();
			};
			// 轮询计数加一,达到MAX_INTERVAL_COUNT时清零
			this.countAdd = function() {
				GS[CLASS_NAME].intervalCount = (GS[CLASS_NAME].intervalCount + 1) % GS[CLASS_NAME].__static.MAX_INTERVAL_COUNT;
			};
			// 读取队列中所有任务并依次执行
			this.executeExecute = function() {
				for ( var x in GS[CLASS_NAME].instances) {
					var p = GS[CLASS_NAME].instances[x];
					if (p == null || p.distroy()) {
						GS[CLASS_NAME].need_distroy_keys[GS[CLASS_NAME].need_distroy_keys.length] = x;// 放入销毁队列
						continue;
					}
					if (GS[CLASS_NAME].intervalCount % p.seconds != 0) {
						continue;
					}
					try {
						p.execute();
					} catch (e) {
					}
				}
			};
			// 销毁失效任务
			this.distroyDistroy = function() {
				for ( var x in GS[CLASS_NAME].need_distroy_keys) {
					try {
						delete GS[CLASS_NAME].instances[x];
					} catch (e) {
						GS[CLASS_NAME].instances[x] == null;
					}
				}
			}
		};
		// 轮询计数
		GS[CLASS_NAME].intervalCount = 0;
		// 6、轮询任务集合
		GS[CLASS_NAME].instances = {};
		// 7、待销毁轮询ID数组
		GS[CLASS_NAME].need_distroy_keys = [];
		// 8、创建伪线程
		GS[CLASS_NAME].interval = setInterval(function() {
			GS[CLASS_NAME].__static.countAdd();
			GS[CLASS_NAME].__static.executeExecute()
			GS[CLASS_NAME].__static.distroyDistroy();
		}, GS[CLASS_NAME].__static.TIME_CLOCK);
		return GS[CLASS_NAME];
	};
	if (!!window.f) {
		return polling_install(f.top());
	} else {
		return polling_install;
	}
});
/**
 * 
 * 示例:
 * 
 * new Polling({ url:"/a/b/c", data:{ deviceType:32 }, success:function(res){
 * alert(res); } });
 */
// 文档说明:
// ┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
// ┃属性 ┃接收参数 ┃是否必填 ┃默认值 ┃说明 ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃id ┃string ┃否 ┃随机字符串 ┃任务标识 ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃url ┃function/string ┃否 ┃无 ┃请求URL ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃data ┃function/object/queryString┃否 ┃无 ┃请求数据 ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃success ┃function(res) ┃是 ┃无 ┃请求回调函数 ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃seconds ┃number ┃否 ┃5 ┃调度周期(秒) ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃enable ┃function/boolean ┃否 ┃页面跳转后无效 ┃使定时器失效 ┃
// ┣━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
// ┃distroy ┃function/boolean ┃否 ┃调用enable ┃使定时器销毁 ┃
// ┗━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值