javascriptsynchronizationscheduled-taskssettimeoutsetinterval

How does one enforce a chron-job to be executed exactly at every possible 5 minute mark (0:00, 0:05, 0:10) regardless of the chron-job's start time?


I have a JavaScript function of chrome extension that I need to run at exact 5-minute intervals, synchronized with the current time. For example, it should run at 5:00, 5:05, 5:10, and so on, regardless of when the script starts running.

Here is the approach I am trying to implement:

Calculate the delay until the next 5-minute mark.
Use setTimeout to call the function at the next 5-minute mark.
Set up a setInterval to call the function every 5 minutes after the initial timeout.
Here is a simplified version of the code to demonstrate the issue:

function myFunction() {
    console.log("Function executed at:", new Date().toLocaleTimeString());
}

function checkTimeAndRunMainFunction() {
    let now = new Date();
    let minutes = now.getMinutes();
    let seconds = now.getSeconds();

    if (seconds === 0 && minutes % 5 === 0) {
        // Run the main function immediately
        myFunction();
    }
}

function calculateDelayToNextFiveMinuteMark() {
    let now = new Date();
    let millisecondsUntilNextFiveMinuteMark = (5 - (now.getMinutes() % 5)) * 60 * 1000 - now.getSeconds() * 1000 - now.getMilliseconds();
    return millisecondsUntilNextFiveMinuteMark;
}

// Set an initial timeout to synchronize with the next 5-minute mark
setTimeout(function() {
    checkTimeAndRunMainFunction();
    // Set an interval to check the time every 5 minutes after the initial call
    setInterval(checkTimeAndRunMainFunction, 5 * 60 * 1000);
}, calculateDelayToNextFiveMinuteMark());

The problem I am facing is that setInterval(checkTimeAndRunMainFunction, 1000); counts every second from the moment the user runs the code, and it does not synchronize with the actual clock's seconds, resulting in the condition if (seconds === 0 && minutes % 5 === 0) not being met precisely.

How can I ensure that my function runs exactly at the 5-minute marks (e.g., 5:00, 5:05, 5:10) regardless of when the script starts running?


Solution

  • Here simple script that runs every 5 minute and adjust next start time on every run

    (function loop() {
      const date = new Date();
      const wait = 300000 - date % 300000
      console.log(date, wait);
    
      setTimeout(() => {
        console.log(new Date())
    
        loop();
        // your code here
      }, wait);
    })();