好的,在将其标记为重复项之前,请阅读全文。
所以,我是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)
从未真正停止原始文档,我感到困惑。
我研究了很多其他类似的问题,似乎我做得对(显然不是)。怎么了?
答案 0 :(得分:0)
问题是,当wallsToggle
首次运行且该功能启动您的计时器时,您仅检查true
中的false
或timerReset
(并可能停止计时器),然后调用wallsTimerPing
,但是timerReset
再也不会运行,因此停止运行计时器的clearInterval()
永远不会被击中。
这里是逐步的:
wallsToggle
设置为true
timerReset()
被呼叫wallsToggle
已针对true
进行了测试wallsToggle
是true
,因此输入了true
的{{1}}分支if
已记录"Timer has been reset"
被调用,但尚未启动任何计时器,所以什么也没发生clearInterval()
被调用,并且当间隔过去后,setInterval()
被放置在事件队列上,并且开始新的间隔计数。wallsTimerProg()
语句已执行,但if
仍为wallsToggle
,因此未输入其true
分支。true
完成。timerReset()
执行。wallsTimerProg()
设置为wallsTimerProg()
的{{1}}中可能发生或未发生wallsToggle
终止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();