Reputation: 41945
I would like to run a function at the beginning of every second.
With the following:
function loop() {
console.log('loop', new Date());
}
setInterval(loop, 1000);
I get this: (running with node v11.13.0)
> node loop.js
loop 2019-04-04T17:37:24.198Z
loop 2019-04-04T17:37:25.222Z
loop 2019-04-04T17:37:26.228Z
loop 2019-04-04T17:37:27.229Z
loop 2019-04-04T17:37:28.230Z
loop 2019-04-04T17:37:29.231Z
loop 2019-04-04T17:37:30.235Z
loop 2019-04-04T17:37:31.239Z
You can see that at each loop, the number of milliseconds is offset by about 200ms, and it is increasing by a few milliseconds each iteration.
Ideally I would want this:
> node loop.js
loop 2019-04-04T17:37:24.000Z
loop 2019-04-04T17:37:25.000Z
loop 2019-04-04T17:37:26.000Z
...
Upvotes: 0
Views: 183
Reputation: 41945
One way is to dynamically adjust the timeout before the next invocation, like so:
function loop() {
let now = new Date();
let millis = now.getMilliseconds();
console.log('loop', now, now.getMilliseconds());
setTimeout(loop, 1000 - millis)
}
loop();
This outputs:
node loop.js
loop 2019-04-04T17:42:55.311Z 311
loop 2019-04-04T17:42:56.022Z 22
loop 2019-04-04T17:42:57.005Z 5
loop 2019-04-04T17:42:58.000Z 0
loop 2019-04-04T17:42:59.001Z 1
loop 2019-04-04T17:43:00.001Z 1
Try for yourself:
function loop() {
let now = new Date();
let millis = now.getMilliseconds();
console.log('loop', now, now.getMilliseconds());
setTimeout(loop, 1000 - millis)
}
loop();
The first invocation is not at the beginning of the second (it's random), and the offset can vary by a few milliseconds in the following iterations. But that might be good enough depending on your use case.
Upvotes: 3