【问题标题】:clearInterval() isn't stopping an intervalclearInterval() 没有停止间隔
【发布时间】:2019-02-16 09:08:41
【问题描述】:

好的,在您将此标记为重复之前,请阅读全文。

所以,我是 JS 新手。我正在尝试做一个计时器。每当调用函数timerReset() 时,都应该重新启动一个间隔。我有这个:

intervalID = setInterval(wallsPingTimer, wallsTime); //INTERVAL IS DEFINED ON STARTUP
wallsTime = 10000;
wallsToggle = true

function timerReset() {
    if (wallsToggle === true) {
        console.log('Timer has been reset');
        clearInterval(intervalID);
        intervalID = setInterval(wallsTimerPing, wallsTime);
    }
    if (wallsToggle === false) {
        console.log('Timer is disabled');
    }
}

function wallsPingTimer() {
//some code
}

计时器在启动intervalID = setInterval(wallsTimerPing, wallsTime) 时启动,但旧计时器从不停止。最终发生的是wallsTimerPing() 一遍又一遍地在多个计时器上执行。 clearInterval(intervalID) 从来没有真正停止过原版,我很困惑。

我查看了很多其他类似的问题,似乎我做对了(显然不是)。怎么回事?

【问题讨论】:

  • setInterval() 将函数引用作为其第一个参数。 wallsTimerPing 是什么?请更新您的问题以显示所有相关代码。
  • 显示的代码看起来正确。您如何使用timerReset 以及您如何得出未重置间隔?
  • clearInterval 后面是代码中的 setInterval,因此 wallTimerPing 函数永远不会停止执行
  • @ScottMarcus 更新,wallTimerPing 是一个函数。 @charlietfl timerReset 由其他函数执行。这是 discord.js 中的一个机器人,所以当使用某个命令时它会被执行。 @Stakvino 计时器应该重新启动,这是故意的。那部分有效,旧的间隔一直在运行......
  • 你定义了使用后的墙壁时间?

标签: javascript node.js discord.js


【解决方案1】:

问题是,当timerReset 第一次运行并且该函数启动您的计时器,然后调用wallsTimerPing 时,您只检查wallsToggletruefalse(并可能停止计时器),但是timerReset 不再运行,因此停止运行计时器的 clearInterval() 永远不会被击中。

这里是一步一步的:

  1. wallsToggle 设置为 true
  2. timerReset() 被调用
  3. wallsToggle 已针对 true 进行测试
  4. wallsToggletrue,因此输入了 iftrue 分支
  5. "Timer has been reset" 已记录
  6. clearInterval() 已被调用,但尚未启动计时器,因此没有任何反应
  7. setInterval() 被调用,当间隔过去时,wallsTimerProg() 被放置在事件队列中并开始新的间隔计数。
  8. 第二个if语句被执行,但是wallsToggle仍然是true所以它的true分支没有进入。
  9. timerReset() 完成。
  10. wallsTimerProg() 执行。
  11. wallsTimerProg() 中可能会或可能不会发生将wallsToggle 设置为false 的事情
  12. wallsTimerProg() 终止
  13. 达到间隔,第 7 步再次发生。
  14. 当调用堆栈空闲时,步骤 10-13 会再次发生。
  15. 第 7 步和第 14 步永远继续,因为wallsTimerProg() 没有清除计时器的代码。

如果计时器递归调用 timerReset,您的模式将是正确的,因为 if/then 测试将在每次调用该函数时运行,clearInterval() 可能会被命中。

let intervalID;
wallsTime = 2000;
wallsToggle = true


function timerReset() {
    console.log("wallsToggle is: " + wallsToggle);
    
    // The code that determines if the timer should continue should 
    // be in the function that will be called repeatedly.
    if (wallsToggle === true) {
        console.log('Timer has been reset');
        intervalID = setInterval(timerReset, wallsTime);
    } else  { // <-- If a Boolean isn't true, it must be false. No need to check
        // Clear the interval when you've determined that you need to stop
        clearInterval(intervalID);  
        console.log('Timer is disabled');
    }
    
  // The main code that this function does here
  // along with something that would change wallsToggle to false
  wallsToggle = false;
}

timerReset();

但是,如果您希望/需要计时器调用第二个函数,那么您需要将确定计时器是否应再次运行的代码移动到 clearInterval() 调用的函数中,而不是运行的函数中一次并开始操作。

以下是它应该如何工作的示例:

let intervalID;
wallsTime = 2000;
wallsToggle = true

function wallsTimerPing(){
    console.log("wallsToggle is: " + wallsToggle);
    
    // The code that determines if the timer should continue should 
    // be in the function that will be called repeatedly.
    if (wallsToggle === true) {
        console.log('Timer has been reset');
    } else  { // <-- If a Boolean isn't true, it must be false. No need to check
        // Clear the interval when you've determined that you need to stop
        clearInterval(intervalID);  
        console.log('Timer is disabled');
    }
    
  // The main code that this function does here
  // along with something that would change wallsToggle to false
  wallsToggle = false;
}

function timerReset() {
   intervalID = setInterval(wallsTimerPing, wallsTime);
}

timerReset();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    相关资源
    最近更新 更多