1

我有一个相当复杂的页面,其中包含许多 ajax 调用和随后的 dom 操作。在一个特定的调用中,它设置一个带有时间限制的间隔(本质上是一个计时器)。我在任何地方,甚至在函数中都设置了clearInterval(),但在非常特殊的用例中(它很复杂,我无法确定重现缺陷的确切原因和步骤)。

$(function() {
  window.timer_interval; 
  // ...
})
function timer()
{
    var current = 0; 
    time_limit = 60;                                
    window.timer_interval = setInterval(function() {
        minute = ( "0" +  Math.round(Math.floor((time_limit - current)/60))).slice(-2); 
        seconds = ("0" + ((time_limit - current)%60)).slice(-2); 

        $('#timer').html(minute + ":" + seconds);

        if (current >= time_limit) {
            clearInterval(window.timer_interval); 
            window.timer_interval = false; 
        }
        current = current + 1; 
    }, 1000);
}

我已经使用 firbug 来检测 的值window.timer_interval,它false甚至满足条件。一件事可能是几个图像传输失败(这是可能的应用程序行为,代码写入优雅降级)。我正在 Mozilla 中开发。

4

1 回答 1

7

我的猜测是您正在设置间隔,然后再次设置间隔而不先清除它,这样之前设置的任何内容都将永远运行。

如果我是对的,添加一个检查以清除之前的间隔setInterval将纠正问题。我为下面的代码创建了一个函数,当您调用setInterval.

// starts an interval function, making sure to cancel one that is previously running
function startSharedInterval(func) {
    if (window.timer_interval) {
        clearInterval(window.intervalID);
        window.timer_interval = 0;
    }

    window.timer_interval = setInterval(func, 1000);
};

// ... in timer() 
startSharedInterval(function () {
    minute = ( "0" +  Math.round(Math.floor((time_limit - current)/60))).slice(-2)  ; 
    // ... rest of code
});

如果您只有一个计时器,那么您可以避免使用全局作用域并利用闭包的优势,以便始终清除计时器。

在下面的代码中,interval_id是在父timer()函数中创建的。这将可供内部匿名函数在 60 后执行完成时清除。您可能有多个实例以这种方式同时运行。

function timer() {

    var current = 0;
    var time_limit = 60;
    var interval_id = setInterval(function () {

        minute = ("0" + Math.round(Math.floor((time_limit - current) / 60))).slice(-2);
        seconds = ("0" + ((time_limit - current) % 60)).slice(-2);

        $('#timer').html(minute + ":" + seconds);

        if (current >= time_limit) {
            clearInterval(interval_id);
        }
        current = current + 1;
    }, 1000);
}
于 2013-08-11T14:21:58.420 回答