繁体   English   中英

setInterval(javaScript):有没有已知的错误?

[英]setInterval (javaScript): are there known bugs?

100次中99次,这完美地运作:

function a(){
   setInterval("b()",1000); 
   updateText("still working");
}
function b(){
   timer++;
   updateText(timer);
}

偶尔第一个循环等待20秒到2分钟。 此后它完美运行。 我知道计时器可以在Android手机上暂停(当显示软键盘时)。 还有其他条件可能延迟setInterval吗?

首先,强烈建议你提供一个回调( function )作为第一个参数而不是字符串,因为该字符串是在全局范围内计算的,我们都知道当我们在js中使用eval时会发生不好的事情(相关的eval post: 什么时候JavaScript的eval()不是邪恶的? )。
所以,你的

setInterval("b()", 1000); 

应改写为:

setInterval(b, 1000); 

要么:

setInterval(function() { b(); }, 1000); 

我还建议您使用setTimeout来模拟setInterval

setInterval函数的主要缺点是它每n毫秒执行一段代码,而不管前一代码块的执行情况如何。
因此,如果由于某种原因, setInterval回调的执行时间比提供的延迟要长,则会导致一些堆栈溢出

我们以下面的代码为例:

function foo() {
    // this takes about 2 seconds to execute
    // .. code here
}
setInterval(foo, 1000);

这实际上将冻结浏览器,因为它将执行foo (几乎)无限次,但它永远不会完成它。

在这种情况下的解决方案是使用setTimeout模拟setInterval ,以确保在再次调用之前回调已完成执行:

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);
}

如果您感兴趣,我已经重写了setIntervalclearInterval函数,以便在任何地方使用它们,而不需要处理堆栈溢出:

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);

要么

setInterval(function(){
   timer++;
   updateText(timer);
}, 1000);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM