clearInterval не сбрасывается

Я пытаюсь создать функцию, которая вычисляет время воспроизведения песни из Spotify, но я застрял на функции clearInterval. Проблема в том, что таймер продолжает ускоряться после того, как я пытаюсь его сбросить. Я использую Reactjs

Первый запуск intervalToTick составляет 1,6 секунды, но если я снова запущу функцию, она удвоится и будет ускоряться при каждом сбросе (работает в первый раз)

Поскольку я использую mobX, мое решение заключалось в том, чтобы добавить myTimer как @observable в магазин, а затем перейти к ответу ниже.

const ticker = function() {
  if (store.timer < 100) {
    store.addToTimer() //mobX store action to add 1+ to the store.timer
  }

};

function progress() {
  store.timer = 0
  let time = Moment()
  let songEnd = Moment().add(1, "minutes")
  const durationToFinnish = Moment.duration(songEnd.diff(time));
  const intervalToTick = 100000 / durationToFinnish.asMilliseconds()

  //Dumb to have it 2 times but cant figure of another way
  var myTimer = window.setInterval(ticker, intervalToTick * 1000);
  clearInterval(myTimer);
  myTimer = window.setInterval(ticker, intervalToTick * 1000);
}
<div className={classes.progressBar} id="progress">
  <div className={classes.innerProgressBar}>
    <span onClick={progress}>{store.timer}%</span><br></br>
  </div>
</div>


person pat    schedule 23.03.2019    source источник


Ответы (1)


Вы должны сделать переменную таймера более широкой, чтобы к ней можно было получить доступ как из progress, так и из ticker, и вам нужно очистить интервал, если он уже запущен, чтобы вы не могли запускать несколько интервалов одновременно:

var myTimer = null; // Declared here so it can be used in both functions

const ticker = function () {
  if(store.timer < 100){
    store.addToTimer() //mobX store action to add 1+ to the store.timer
  }      
};

function progress() {        
  store.timer = 0
  let time = Moment()
  let songEnd = Moment().add(1, "minutes")
  const durationToFinnish = Moment.duration(songEnd.diff(time));
  const intervalToTick = 100000 / durationToFinnish.asMilliseconds()  
  // Check to see if there is already a timer running
  if(myTimer){
    clearInterval(myTimer); // Stop the interval   
  }
  myTimer = setInterval(ticker, intervalToTick * 1000);    
}
<div className={classes.progressBar} id="progress">
            <div className={classes.innerProgressBar}>
                <span onClick={progress}>{store.timer}%</span><br></br>
            </div>
        </div>

person Scott Marcus    schedule 23.03.2019
comment
Я пробовал это и все еще имею ту же проблему. Я не могу иметь clearInterval (myTimer) в функции тикера, так как я хочу, чтобы он продолжал тикать до тех пор, пока функция прогресса не будет запущена снова - person pat; 24.03.2019
comment
Он по-прежнему тикает быстрее при каждом запуске функции прогресса. Но как? это кажется таким странным. Ссылка на видео i.gyazo.com/d5679765fcc18b5c776da1cfce76c4ef.mp4 - person pat; 24.03.2019
comment
@pat Дважды проверьте свою реализацию. Если вы используете код, который я показал (и я снова обновил его для упрощения), второй таймер не сможет запуститься. - person Scott Marcus; 24.03.2019
comment
Я добавил myTimer в хранилище mobX как переменную @observable, и все заработало! Но я не знаю, как это не сработало, чтобы объявить его наверху, как это сделали вы. - person pat; 24.03.2019