简体   繁体   English

clearInterval 在 setInterval 内不起作用

[英]clearInterval not working inside setInterval

I'm trying to build a countdown timer, which has a single button to toggle the start and the stop of the timer.我正在尝试构建一个倒数计时器,它有一个按钮来切换计时器的开始和停止。 Starting the timer and the switch between "break mode" and "session mode" works fine.启动计时器并在“中断模式”和“会话模式”之间切换工作正常。 The initial state of the countdown timer is paused.倒数计时器的初始 state 暂停。 When I click on the Toggle Button it starts normally.当我单击切换按钮时,它会正常启动。 When I click again, it doesn't do anything, it doesn't clear the interval.当我再次单击时,它什么也不做,它不清除间隔。 When I click again however, it doubles the interval.但是,当我再次单击时,它会加倍间隔。

Here is my code so far - the countdown function and the toggle function:到目前为止,这是我的代码 - 倒计时 function 和切换 function:

  startstop() {
    if (this.state.paused){
      this.setState({
        paused: false,
      });
      this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, this.state.paused);
    } else if (!this.state.paused){
      this.setState({
        paused: true,
      });
      this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, this.state.paused);
    }
  }

 countdown(seconds, minutes, sessionactive, pausedtrue){
  let s = seconds;
  let m = minutes;
  let interval = setInterval(() => {
    if (pausedtrue){
      clearInterval(interval);
    } else {
      if (s === 0 && m > 0){
        this.setState({
          timerseconds: 59,
          timerminutes: this.state.timerminutes - 1
        })
        s = 59;
        m = m - 1;
      } else if (s > 0 && m >= 0) {
        this.setState({
          timerseconds: this.state.timerseconds - 1,
          timerminutes: this.state.timerminutes
        })
        s = s - 1;
      } else if (s === 0 && m === 0){
        if (sessionactive){
          clearInterval(interval);
          document.getElementById("beep").play();
          this.setState({
            timerseconds: 0,
            timerminutes: this.state.breaklength,
            sessiontrue: false,
          });
          this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, false);
        } else {
          clearInterval(interval);
          document.getElementById("beep").play();
          this.setState({
            timerseconds: 0, 
            timerminutes: this.state.sessionlength,
            sessiontrue: true,
          });
          this.countdown(this.state.timerseconds, this.state.timerminutes, this.state.sessiontrue, false)
        }
      }
    }
  }
, 1000)
}

Every time you call countdown you create a new interval.每次您调用countdown ,您都会创建一个新的间隔。 You should store the reference to the first interval somewhere and use that reference in clearInterval when you click to pause the timer.您应该在某处存储对第一个间隔的引用,并在单击暂停计时器时在clearInterval中使用该引用。

Another approach would be to use this.state.paused instead of pausedtrue in if (pausedtrue) , because pausedtrue is set when you call the method and never changes but this.state.paused can be changed and will be checked every tick.另一种方法是在if (pausedtrue)中使用this.state.paused而不是pausedtrue ,因为在调用该方法时设置了pausedtrue并且永远不会更改,但是this.state.paused可以更改,并且会在每个滴答声中检查。

Also I think it's not safe to use this.state.paused when you call the countdown .另外我认为在调用countdown时使用this.state.paused是不安全的。 setState is asynchronous so you never know if the value in the state has been already changed or not. setState是异步的,因此您永远不知道 state 中的值是否已经更改。

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

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