javascripttimesynchronizationsetinterval

Interval synced to Time


I want to execute a function in an interval. Yeah I could use setInterval but I need the interval to be synced to the timestamp or something.

Like I want to execute the interval on two different devices and they should run in the exact same second or even ms if possible. But depending on when I star the script these intervals would be offset if I would use setInterval method.

I've already tried this but it kinda acts weird.

setInterval(() => {
        if (new Date().getTime() % 1000 * 10 == 0) {
            console.log(new Date().toLocaleTimeString())
        }
    }, 1);

Solution

  • Like I want to execute the interval on two different devices and they should run in the exact same second or even ms if possible.

    There's no guarantee that you can do this, not least because the JavaScript thread on one of the devices may be busy doing something else at that precise moment (it could even be tied up for several seconds).

    Other than that, there's the issue of synchronizing the devices. Options are:

    1. Some kind of synchronization event you send simultaneously to both devices. You'd run your code in response to the synchronization event received from your server. This is naturally subject to network delays, it requires a server to send the event (probably over web sockets), and is subject to the above caveat about the JavaScript thread being busy.

    2. Relying on the devices being synced to exactly the same time source (for instance, perhaps they're both using a NIST time server or similar). If you know their times are synchronized sufficiently for your purposes, you can schedule your timer to fire at a precise moment, like this:

      // Fire at exactly 14:30 GMT on 2021-04-21
      const target = new Date(Date.UTC(2021, 3, 21, 14, 30)); // 3 = April, starts with 0 = Jan
      const delay = Date.now() - target;
      if (delay < 0) {
          // It's already later than that
      } else {
          setTimeout(() => {
              // Your code here
          }, delay);
      }
      

      BUT, again, if the JavaScript thread is busy at that precise moment, the timer callback will run later, when the thread is free.

      The code above schedules a single event, but if you need a recurring one, you can do the same basic logic: Determine the date/time you want the next callback to occur, find out how many milliseconds it is between now and then (Date.now() - target), and schedule the callback for that many milliseconds later.