最近在做用setInterval在做定时器的时候,发现一些问题。
就是一旦定时器中一旦任务执行时间超过定时间隔时间得时候,JavaScript不会等待这次任务执行完毕,重现计算时间间隔,而是到时间间隔一到立马将下次任务加入队列,并且等待该次任务执行完毕后,立马执行,所有定时加载变成循环加载。这是我们所不愿意见到的。
setInterval代码:
function startFn2() {
var p2 = new AlarmClockByInterval(callBackByTest, 2000);
}
function callBackByTest() {
var i = 0;
for (; i < 900000000; i++) {
}
return true;
}
function AlarmClockByInterval(_args1, _args2) {
var timeFn, self = this,
callBackFn = _args1,
ms = _args2,
i = 0;
this.getInterval = function() {
if (ms) {
if (!timeFn) {
timeFn = setInterval(function() {
console.log("定时任务开始执行:"+new Date().getTime());
callBackFn();
console.log("定时任务结束执行:"+new Date().getTime());
}, ms);
}
} else {
closeInterval();
}
}
this.closeInterval = function() {
if (timeFn) {
clearInterval(timeFn);
}
}
self.getInterval();
}大家可以看到,定时任务一旦执行完毕,立马进行下一次任务,并没有理想中的间隔。
任务执行时间也被计算到间隔时间了。直接用setInterval并不能获得我们理想中的效果。
解决:
使用setTimeOut,和递归,利用函数自动调用自身,很延时执行就可以很好的解决这个问题。
function AlarmClockByTimeOut(_args1, _args2) {
var _type = 0,
timeFn, _flag = true,
ms = _args2,
callBackFn = _args1,
self = this;
this.getTimeOut = function() {
var _callee = arguments.callee;
if (_flag) { //内部错误,内部强制中断,终止递归
if (_type == 0) { //外部终止递归
timeFn = setTimeout(function() {
console.log("定时任务开始执行:"+new Date().getTime());
_flag = callBackFn();
console.log("定时任务结束执行:"+new Date().getTime());
_callee();
}, ms);
} else {
if (timeFn) clearTimeout(timeFn);
console.error(500, "定时器已终止,外部终止...");
}
} else {
if (timeFn) clearTimeout(timeFn);
console.error(500, "定时器已终止,回调函数出现错误或内部强制终止...");
}
};
this.close = function(_args1) {
_type = _args1 || 1;
};
self.getTimeOut();
}
function startFn2() {
var p1 = new AlarmClockByTimeOut(callBackByTest,1000);
// var p2 = new AlarmClockByInterval(callBackByTest, 2000);
}执行效果:
这样每次执行完成都会等1000ms,才去加载下一次任务。第一次写博客,有啥问题欢迎讨论
本文出自 “子莫首” 博客,请务必保留此出处http://zimoushou.blog.51cto.com/4306790/1727652
原文地址:http://zimoushou.blog.51cto.com/4306790/1727652