最近在做用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,才去加载下一次任务。第一次写博客,有啥问题欢迎讨论