首先,我们强烈建议您提供一个回调(function
)作为第一个参数,而不是一个字符串,因为该字符串的评估全球范围内,我们都知道,当我们在js中使用eval
时,会发生不好的事情(相关eval post:When is JavaScript's eval() not evil?)。
所以,你
setInterval("b()", 1000);
应该写成:
setInterval(b, 1000);
或:
setInterval(function() { b(); }, 1000);
我也建议你使用setTimeout
模拟setInterval
。
setInterval
函数的主要缺点是它每执行一个代码块就会执行一个代码块,而不管前面的代码块是否执行。
所以如果由于某种原因setInterval
回调需要比提供的延迟执行更长的时间,它将导致一些stack overflows。
让我们以下面的代码,例如:
function foo() {
// this takes about 2 seconds to execute
// .. code here
}
setInterval(foo, 1000);
这实际上将冻结浏览器,因为它会执行foo
为倍(几乎)无限的数字,但它永远不会完成它。
在这种情况下的解决方案是仿效setInterval
与setTimeout
,以保证再次调用它之前的回调完成执行:现在
function foo() {
// this takes about 2 seconds to execute
// .. code here
}
function newSetInterval(callback, duration, callbackArguments) {
callback.apply(this, callbackArguments);
var args = arguments,
scope = this;
setTimeout(function() {
newSetInterval.apply(scope, args);
}, duration);
}
newSetInterval(foo, 1000);
,foo
又被称为后,才前一个实例已完成代码执行。
我将适用同样的事情在你的代码,为了让浏览器决定时,它可以执行的代码,而不是强制执行代码天气的块是忙碌的那一刻与否:
function a() {
newSetInterval(b, 1000);
updateText("still working");
}
function b() {
timer++;
updateText(timer);
}
function newSetInterval(callback, duration, callbackArguments) {
callback.apply(this, callbackArguments);
var args = arguments,
scope=this;
setTimeout(function() {
newSetInterval.apply(scope, args);
}, duration);
}
如果你有兴趣,我已经重写了setInterval
和clearInterval
功能,以便在任何地方使用它们,没有照顾堆栈溢出的:
function setInterval(f, time) {
setInterval.ids = setInterval.ids || {};
setInterval.idCount = setInterval.idCount || 0;
var that = this,
id = setInterval.idCount++,
// to prevent firefox bug that adds an extra element to the arguments
l = arguments.length - 2;
(function theFn() {
// to prevent firefox bug that adds an extra element to the arguments
var args = [].slice.call(arguments, 0, l);
f.apply(this, args);
setInterval.ids[id] = setTimeout.apply(this, [theFn, time].concat(args));
}).apply(that, [].slice.call(arguments, 2, arguments.length));
return id;
}
function clearInterval(id) {
if(!setInterval.ids || !setInterval.ids[id]) {
return false;
}
clearTimeout(setInterval.ids[id]);
return true;
}
请使用'的setInterval(b,1000);而不是 - 不要使用字符串。 – pimvdb
如果文档中使用异步“线程”(例如AJAX)的JavaScript代码更多,它可能会延迟。 –
阅读此:http://ejohn.org/blog/how-javascript-timers-work/ – c69