clearInterval()不会停止间隔

时间:2018-09-11 19:38:06

标签: javascript node.js discord.js

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

所以,我是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)从未真正停止原始文档,我感到困惑。

我研究了很多其他类似的问题,似乎我做得对(显然不是)。怎么了?

1 个答案:

答案 0 :(得分:0)

问题是,当wallsToggle首次运行且该功能启动您的计时器时,您仅检查true中的falsetimerReset(并可能停止计时器),然后调用wallsTimerPing,但是timerReset再也不会运行,因此停止运行计时器的clearInterval()永远不会被击中。

这里是逐步的:

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

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

timerReset

但是,如果您希望/需要计时器调用第二个函数,则需要移动确定计时器是否应再次运行到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();