How can I run 2 counters consecutively with javascript?

Viewed 34

I have 1 counter. The counter will count down from 25 first. It will then start counting down from 10 when this time is up. When this time is over, it will start counting down from 25 again. That's how it will go. How can I do it?

var interval10 = 10000;
var interval = 25000;
  
function tensecond() {
 var remaining = interval10 - (Date.now() % interval10);
}

setInterval(function () {
    if (remaining >= 100) {
        document.getElementById("timer").innerText =
            millisToMinutesAndSeconds(remaining);
    } else {
        reset();
    }
}, 100);

function reset() {
    var remaining = interval - (Date.now() % interval);
}
setInterval(function () {
    if (remaining >= 100) {
        document.getElementById("timer").innerText =
            millisToMinutesAndSeconds(remaining);
    } else {
        tensecond();
    }
}, 100);


function millisToMinutesAndSeconds(millis) {
    var seconds = Math.floor((millis % 60000) / 1000);
    return (seconds < 10 ? "0" : "") + seconds;
}
3 Answers

I'm not entirely sure what you were trying to do in your code. It's easier if you run one interval every second and keep track of which counter you're in and how much time there's left. Like this:

let timeLeft = 25;
let counter = false; // false = 25 sec counter, true = 10 sec counter

setInterval(() => {
    if (timeLeft !== 0) return timeLeft--;
    if (!counter) {
        timeLeft = 10;
        counter = true;
        // do some more stuff
    } else {
        timeLeft = 25;
        counter = false;
        // do some more stuff
    }
}, 1000);

Perhaps you had in mind such an implementation? Each task triggers the following

const interval10 = 1000;
const interval = 2500;

let remaining;

function print(rem, type) {
  if (remaining >= rem) {
    document.getElementById("timer").innerText =
      millisToMinutesAndSeconds(remaining);
  } else {
    if (type === '25') {
      reset()
    } else {
      tensecond()
    }
  }
}

function tensecond() {
  remaining = interval10 - (Date.now() % interval10);
}

function run25() {
  setTimeout(function () {
    print(100, '25')
    run10()
  }, interval);

}

function run10() {
  setTimeout(function () {
    print(100, '10')
    run25()
  }, interval10);
}

function reset() {
  remaining = interval - (Date.now() % interval);
}

function millisToMinutesAndSeconds(millis) {
  const seconds = Math.floor((millis % 60000) / 1000);
  return (seconds < 10 ? "0" : "") + seconds;
}

run25();
  • delete code duplication

The best way to deal with this is to use promises. Each countdown is a promise which resolves once the timer is expired. This way you can chain any number of timers.

SPEED = 100 // set to 1000 to use seconds

function timer(secs, target) {
  let endTime = Number(new Date()) + (secs + 1) * SPEED

  return new Promise(resolve => {
    function step() {
      let now = Number(new Date())
      if (now >= endTime) {
        target.innerText = '0'
        return resolve()
      }
      target.innerText = Math.floor((endTime - now) / SPEED)
      window.requestAnimationFrame(step)
    }
    step()
  })
}

async function loop() {
  while (1) {
    await timer(30, document.querySelector('#a'))
    await timer(20, document.querySelector('#b'))
    await timer(10, document.querySelector('#c'))
  }
}

window.onload = loop
<body style="font-size: 30px">

  <div id="a"></div>
  <div id="b"></div>
  <div id="c"></div>

</body>

Related