/*******************-------------注释掉的是通过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 ┃使定时器销毁 ┃
// ┗━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛