1

Timer is displayed as if it is kind of stop after pause button is clicked, but when i click resume i find out that counter continue to countdown behind the scene. I guess there are issues with setInterval. Please help me. My project on CodePen for reference if you need.

My timer function

function timer(seconds) {
  clearInterval(countdown);
  const now = Date.now();
  const then = now + seconds * 1000;
  displayTimerLeft(seconds);
  console.log({
    now,
    then
  });
  countdown = setInterval(() => {
    if (!isPaused) {
      const remainSeconds = Math.round((then - Date.now()) / 1000);
      if (remainSeconds < 0) {
        clearInterval(countdown);
        return;
      }
      displayTimerLeft(remainSeconds);

    }
  }, 1000);

}

Pause and start click events

pause.addEventListener('click', function() {
  isPaused = true;
  return;

})

start.addEventListener('click', function() {
  isPaused = false;
})
NZMAI
  • 536
  • 5
  • 27
  • 1
    A few pointers. First, don't use 'then' as your const. 'then' is a keyword in js, used in 'if then' statements. When js takes issue with an item, it often skips the rest of the function, so changing your variable name might fix it. Although, you should also use 'variable = undefined' whenever your use clearInterval(variable), otherwise it won't kill it all the way. – EvSunWoodard Jan 10 '17 at 16:00
  • Possible duplicate of [Javascript - Pausing setInterval()](http://stackoverflow.com/questions/21277900/javascript-pausing-setinterval) – bobjoe Jan 10 '17 at 16:01
  • @bobjoe It is not a duplicate actually, the problem comes from him not using a variable to countdown seconds but instead keeping the end timestamp unchanged even when paused. His code snippet is almost exactly the same as the answer in the post you linked. – Marc-Antoine Parent Jan 10 '17 at 16:04

3 Answers3

4

Looking at your code, I suppose the problem is you keep the same then value, which is ultimately a timestamp at which the timer should end. Right now, instead of pausing the countdown, you stop the display from changing.

I would advise using your variable seconds instead (and calculating display using modulo %), and decreasing it every second. That way, pausing the display would effectively pause the decreasing.

2

Keep a reference of the current time and manually add a second at each tick.

function timer(seconds) {
  clearInterval(countdown);
  const t = new Date();
  const end = t.getTime() + seconds * 1000;
  displayTimerLeft(seconds);
  console.log({
    t,
    end
  });
  countdown = setInterval(() => {
    if (!isPaused) {
      const remainSeconds = Math.round((end - t.getTime()) / 1000);
      if (remainSeconds < 0) {
        clearInterval(countdown);
        return;
      }
      displayTimerLeft(remainSeconds);
      t.setSeconds(t.getSeconds() + 1);
    }
  }, 1000);
}

Demo: http://codepen.io/miguelmota/pen/wgMzXY

Miguel Mota
  • 20,135
  • 5
  • 45
  • 64
-2

setInterval returns a unique id that can be used to stop the timer using clearInterval:

var id = setInterval(function(){
console.log('running every 300 ms');
},300);

clearInterval(id) // stop timer
Akram Saouri
  • 1,179
  • 8
  • 15