setInterval (javaScript):是否有已知的错误?
100 次中有 99 次这是完美的:
function a(){
setInterval("b()",1000);
updateText("still working");
}
function b(){
timer++;
updateText(timer);
}
有时第一个循环会等待 20 秒到 2 分钟。此后就完美运行了。我知道计时器可以在 Android 手机上暂停(当显示软键盘时)。是否还有其他条件可能会延迟 setInterval?
99 times out of 100, this works perfectly:
function a(){
setInterval("b()",1000);
updateText("still working");
}
function b(){
timer++;
updateText(timer);
}
Occasionally the first loop waits for 20 seconds to 2 minutes. Thereafter it runs perfectly. I know the timer can pause on Android phones (when the soft keyboard is shown). Are there other conditions that might delay setInterval?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,强烈建议您提供回调(
function
)作为第一个参数而不是字符串,因为该字符串是在全局范围内计算的,我们都知道当我们使用 < 时会发生不好的事情。 js 中的 code>eval (相关 eval 帖子:什么时候是 JavaScript 的 eval()不是邪恶?)。因此,您
应该重写为:
或:
我还建议您使用
setTimeout
来模拟setInterval
。setInterval
函数的主要缺点是它每n
毫秒执行一个代码块,而不管前一个代码块的执行情况。因此,如果由于某种原因
setInterval
回调的执行时间比提供的延迟时间长,则会导致一些堆栈溢出。让我们以下面的代码为例:
这实际上会冻结浏览器,因为它将执行 foo(几乎)无限次,但永远不会完成。
这种情况的解决方案是用
setTimeout
模拟setInterval
,以确保回调在再次调用之前已完成执行:现在,
foo
仅在前一个实例完成代码执行后才会再次调用。我会将同样的事情应用于您的代码,以便让浏览器决定何时可以执行代码,而不是强迫它执行代码块(无论当时是否繁忙):
如果您感兴趣,我重写了
setInterval
和clearInterval
函数,以便在任何地方使用它们,而无需处理堆栈溢出:Firstly, it is strongly advised you provide a callback(
function
) as the first argument and not a string, because that string is evaluated in the global scope and we all know that bad things happen when we useeval
in js (related eval post : When is JavaScript's eval() not evil?).So, your
should be rewritten as :
or:
I also recommend you use
setTimeout
to simulate asetInterval
.The main downfall of the
setInterval
function is that it executes a block of code everyn
milliseconds, regardless of the execution of the previous block of code.So if for some reason a
setInterval
callback takes longer to execute than the delay provided, it will cause some stack overflows.Let's take the following code for example :
This will actually freeze the browser because it will execute
foo
for an (almost) infinite number of times but it will never finish it.The solution in this kind of case is to emulate the
setInterval
withsetTimeout
, in order to ensure that the callback has finished to execute before calling it again:Now,
foo
is called again only after the previous instance has finished the code execution.I would apply the same thing to your code, in order to let the browser decide when it can execute the code, and not to force it to execute the block of code weather it's busy at that moment or not:
If you're interested, I've rewritten the
setInterval
andclearInterval
functions in order to use them anywhere, without taking care of stack overflows :试试这个,
或者
try this,
or