ES6 version, works in NodeJS and all modern browsers - executes on millisecond according to browser or server clock:
---------- UPDATED ----------
Function
const doSomething = something => {
setTimeout(() => {
something()
doSomething(something)
}, 3600000 - new Date().getTime() % 3600000)
}
Usage
// Do something at next full hour and repeat forever
doSomething(() => console.log('Full hour reached!'))
---------- OLD ANSWER WITH MORE CONTROL ----------
Function
const doSomething = (something) => {
let running = true
let nextHour = () => {
return 3600000 - new Date().getTime() % 3600000
}
let nextCall = setTimeout(() => {
something()
doSomething(something)
}, nextHour())
return {
next() { return running ? nextHour() : -1 },
exec() { something() },
stop() {
clearTimeout(nextCall)
running = false
},
start() {
clearTimeout(nextCall)
nextCall = setTimeout(() => {
something()
doSomething(something)
}, nextHour())
running = true
}
}
}
Usage
// Do something at next full hour and repeat forever
doSomething(() => console.log('Full hour reached!'))
// Do something every full hour & stop it
let obj = doSomething(() => console.log('Will I ever execute? :/'))
obj.next() // Time to next execution in milliseconds
obj.next() / 1000 // Time to next execution in seconds
obj.next() / 1000 / 60 // Time to next execution in minutes
obj.stop() // Stop executing every full hour
obj.start() // Continue executing every hour
obj.exec() // Execute now