Home > Software design >  Countdown inside a setInterval which is inside a SetTimeout Function
Countdown inside a setInterval which is inside a SetTimeout Function

Time:09-26

What I was trying to do was to display countdown timers to datetimes in an array one by one. But what happens is for the first loop, it displays correctly. the subsequent iterations are displaying both the values and the "Countdown" element in html is glitching and switching between those values.

The code that I am using is below:

function padZero(time) {
  return time < 10 ? '0'   time : ''   time;
}
var found = ["2022-10-01 10:00", "2022-10-02 11:00", "2022-10-03 02:00", "2022-10-04 12:00"];
var interval1 = 30000 / found.length;
(function myLoop(i) {
  setTimeout(function() {
    console.log(found[i]);
    var eventTime, currentTime, duration, interval, intervalId;
    interval = 100;
    var eventTime = new moment(found[i], 'YYYY-MM-DD HH:mm:ss.SS');
    currentTime = moment().format('YYYY-MM-DD HH:mm:ss.SS');
    duration = moment.duration(eventTime.diff(currentTime));
    setInterval(function() {
      duration = moment.duration(duration - interval, 'milliseconds');
      if (duration.asSeconds() <= 0) {
        clearInterval(intervalId);
        $(".countdown").hide();
      } else {
        var countout = padZero(duration.days())   " days "   padZero(duration.hours())   ":"   padZero(duration.minutes())   ":"   padZero(duration.seconds())   "."   padZero(duration.milliseconds() / 10 | 0);
        console.log(countout);
        $(".countdown").html(countout);
      }
    }, interval);
    if (--i) myLoop(i);
  }, interval1);
})(found.length - 1);
<body>
  <div ></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Output :

2022-10-04 12:00
09 days 02:03:18.70
09 days 02:03:18.20
09 days 02:03:17.70
09 days 02:03:17.20
09 days 02:03:16.70
09 days 02:03:16.20
09 days 02:03:15.70
09 days 02:03:15.20
09 days 02:03:14.70
09 days 02:03:14.20
09 days 02:03:13.70
09 days 02:03:13.20
09 days 02:03:12.70
09 days 02:03:12.20
09 days 02:03:11.70
2022-10-03 02:00
09 days 02:03:11.20
07 days 16:03:11.19
09 days 02:03:10.70
07 days 16:03:10.69
09 days 02:03:10.20
07 days 16:03:10.19
09 days 02:03:09.70
07 days 16:03:09.69
09 days 02:03:09.20
07 days 16:03:09.19
09 days 02:03:08.70
07 days 16:03:08.69
09 days 02:03:08.20
07 days 16:03:08.19
09 days 02:03:07.70
07 days 16:03:07.69
09 days 02:03:07.20
07 days 16:03:07.19
09 days 02:03:06.70
07 days 16:03:06.69
09 days 02:03:06.20
07 days 16:03:06.19
09 days 02:03:05.70
07 days 16:03:05.69
09 days 02:03:05.20
07 days 16:03:05.19
09 days 02:03:04.70
07 days 16:03:04.69
09 days 02:03:04.20
07 days 16:03:04.19
2022-10-02 11:00
09 days 02:03:03.70
07 days 16:03:03.69
07 days 01:03:03.69
09 days 02:03:03.20
07 days 16:03:03.19
07 days 01:03:03.19
09 days 02:03:02.70
07 days 16:03:02.69
07 days 01:03:02.69
09 days 02:03:02.20
07 days 16:03:02.19
07 days 01:03:02.19
09 days 02:03:01.70
07 days 16:03:01.69
07 days 01:03:01.69
09 days 02:03:01.20
07 days 16:03:01.19
07 days 01:03:01.19
09 days 02:03:00.70
07 days 16:03:00.69
07 days 01:03:00.69
09 days 02:03:00.20
07 days 16:03:00.19
07 days 01:03:00.19
09 days 02:02:59.70
07 days 16:02:59.69
07 days 01:02:59.69
09 days 02:02:59.20
07 days 16:02:59.19
07 days 01:02:59.19
09 days 02:02:58.70
07 days 16:02:58.69
07 days 01:02:58.69
09 days 02:02:58.20
07 days 16:02:58.19
07 days 01:02:58.19
09 days 02:02:57.70
07 days 16:02:57.69
07 days 01:02:57.69
09 days 02:02:57.20
07 days 16:02:57.19
07 days 01:02:57.19
09 days 02:02:56.70
07 days 16:02:56.69
07 days 01:02:56.69
09 days 02:02:56.20
07 days 16:02:56.19
07 days 01:02:56.19
09 days 02:02:55.70
07 days 16:02:55.69
07 days 01:02:55.69
09 days 02:02:55.20

The actual output that I want is :

2022-10-04 12:00
09 days 02:03:18.70
09 days 02:03:18.20
09 days 02:03:17.70
09 days 02:03:17.20
09 days 02:03:16.70
09 days 02:03:16.20
09 days 02:03:15.70
09 days 02:03:15.20
09 days 02:03:14.70
09 days 02:03:14.20
09 days 02:03:13.70
09 days 02:03:13.20
09 days 02:03:12.70
09 days 02:03:12.20
09 days 02:03:11.70
2022-10-03 02:00
07 days 16:03:11.19
07 days 16:03:10.69
07 days 16:03:10.19
07 days 16:03:09.69
07 days 16:03:09.19
07 days 16:03:08.69
07 days 16:03:08.19
07 days 16:03:07.69
07 days 16:03:07.19
07 days 16:03:06.69
07 days 16:03:06.19
07 days 16:03:05.69
07 days 16:03:05.19
07 days 16:03:04.69
07 days 16:03:04.19
2022-10-02 11:00
07 days 01:03:03.69
07 days 01:03:03.19
07 days 01:03:02.69
07 days 01:03:01.69
07 days 01:03:01.19
07 days 01:03:00.69
07 days 01:03:00.19
07 days 01:02:59.69
07 days 01:02:59.19
07 days 01:02:58.69
07 days 01:02:58.19
07 days 01:02:57.69
07 days 01:02:57.19
07 days 01:02:56.69
07 days 01:02:56.19
07 days 01:02:55.69

Can anyone help me with this?

CodePudding user response:

duration.asSeconds() always larger than 0. so clearInterval didn't work.

function padZero(time) {
  return time < 10 ? '0'   time : ''   time;
}
var found = ["2022-10-01 10:00", "2022-10-02 11:00", "2022-10-03 02:00", "2022-10-04 12:00"];
var interval1 = 30000 / found.length;
(function myLoop(i) {
  setTimeout(function() {
    console.log(found[i]);
    var eventTime, currentTime, duration, interval, intervalId;
    interval = 500;
    var eventTime = new moment(found[i], 'YYYY-MM-DD HH:mm:ss.SS');
    currentTime = moment().format('YYYY-MM-DD HH:mm:ss.SS');
    duration = moment.duration(eventTime.diff(currentTime));

    var count = 0;
    
    setInterval(function() {
      duration = moment.duration(duration - interval, 'milliseconds');

      let intervalMs = interval * count  ;

      if (interval1 - intervalMs <= 0) {
        clearInterval(intervalId);
      } else {
        var countout = padZero(duration.days())   " days "   padZero(duration.hours())   ":"   padZero(duration.minutes())   ":"   padZero(duration.seconds())   "."   padZero(duration.milliseconds() / 10 | 0);
        console.log(countout);
        $(".countdown").html(countout);
      }
    }, interval);
    if (--i >= 0) myLoop(i);
  }, interval1);
})(found.length - 1);
<body>
  <div ></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

  • Related