You can make setTimeout
"recursive" (it is not technically recursion), to call the scheduler function again after the previous is triggered.
Note: this is a pure JS solution, so it will work on every environment, but as setTimeout
is inaccurate, this isn't the best option if you need high accuracy.
function onTime(cb, h = 0, m = 0, s = 0, ms = 0){
let id
void function r(){
let timeUntilNextOccurrence = new Date().setHours(h, m, s, ms) - Date.now()
if(timeUntilNextOccurrence <= 0)
timeUntilNextOccurrence += 86400000
id = setTimeout(() => {
cb()
r()
}, timeUntilNextOccurrence)
}()
return function cancel(){
clearTimeout(id)
}
}
const cancel = onTime(() => console.log("It's 8 am!"), 8, 0, 0)
You can cancel it using the function it returns.