0

I'm looking for an efficient (not continuous polling) way to execute a function whenever the real time clock turns over to a new minute. My current code uses setInterval to call the function every 60 seconds -- but in practice there is some lagging and the function is getting called at about 60.2 seconds on average. This is leading to a cumulative error that builds up in a process monitoring system I'm developing.

Does anyone out there have a clever bit of code that calls a function at regular intervals triggered by the real time clock?

Edit: I was alerted to a method to compensate for the error by checking the time each time the function was called and compensating the setInterval value for the next call. This gets me closer -- but what I'm really after is a method to call a function right at the start of a new minute according to the real time clock...

  • possible duplicate of [setInterval timing slowly drifts away from staying accurate](http://stackoverflow.com/questions/8173580/setinterval-timing-slowly-drifts-away-from-staying-accurate) – Josh May 19 '15 at 03:00
  • possible duplicate of [How to create an accurate timer in javascript?](http://stackoverflow.com/q/29971898/1048572) – Bergi May 19 '15 at 04:46

1 Answers1

3

Yes, if you use setInterval with an interval of 1 minute, it will eventually start to drift, as you've observed. You don't have to continuously poll, though: you just have to use chained calls to setTimeout. Each one checks itself against the clock. Sometimes the timeout will be 59999, sometimes it will be 59997, etc. But it will always be keeping in step with the clock.

function everyMinuteOnTheMinute() {
    setTimeout(function() {
        var d = new Date();
        console.log(d.getMinutes() + " (" + d.valueOf() % 1000 + ")");
        // your "every minute" code goes here
        everyMinuteOnTheMinute();
    }, 60000 - Date.now() % 60000);
}

You can turn this into a general utility by adding a callback:

function everyMinuteOnTheMinute(cb) {
    setTimeout(function() {
        cb();
        everyMinuteOnTheMinute(cb);
    }, 60000 - Date.now() % 60000);
}

Then when you have code you need to run every minute on the minute, just use the utility function:

everyMinuteOnTheMinute(function() {
    console.log("Whee, I'm happening every minute on the minute!");
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • 1
    `everyMinute` is not a function… Did you mean to recursively call something? – Bergi May 19 '15 at 04:47
  • Yes, I did, thanks for the catch, Bergi. I decided to rename it so that it's more explicit (`everyMinute` doesn't necessarily mean "on the minute"), but forgot to change the invocation, – Ethan Brown May 19 '15 at 05:17