Can NodeJS setTimeout
delay excecution of function for a week? (assuming the server doesnt go down...)
In some other servers like ASP.NET CORE, the server will sleep when not in use, hence we can't use such.
Does the same happen in the NodeJS world, or the server remains on forever?
Can NodeJS setTimeout
delay excecution of function for a week? (assuming the server doesnt go down...)
In some other servers like ASP.NET CORE, the server will sleep when not in use, hence we can't use such.
Does the same happen in the NodeJS world, or the server remains on forever?
setTimeout
has the second argument of delay as a 32-bit signed integer. So the value can not be greater than 2147483647 (about 24.8 days). When the delay is larger than 2147483647, then the delay will set to 1. (ref)
Instead of using setTimeout
for such a long delay, you can run cron job.
There is nothing in the documentation that would suggest it would not work. However, if the length in millisecond is greater than 2147483647
(24 day 20 h 31 min 24 s), the delay is set to 1.
https://nodejs/api/timers.html#timers_settimeout_callback_delay_args
The behavior is different on a browser. Unsurprisingly, the timeout is delayed if the associated tab is inactive.
If the method context is a Window object, wait until the Document associated with the method context has been fully active for a further timeout milliseconds (not necessarily consecutively).
Otherwise, if the method context is a WorkerUtils object, wait until timeout milliseconds have passed with the worker not suspended (not necessarily consecutively).
https://www.w3/TR/2011/WD-html5-20110525/timers.html#dom-windowtimers-settimeout
Here is a solution to get timeout longer than 24.8 days. for those who are looking.
/**
* If the timeout is greater than `maxDelay`, it calculates the number of
* expected ticks required to achieve the desired timeout duration.
*
* It then sets up an interval with a callback function that decrements the
* expectedTicks count on each tick.
*
* When expectedTicks reaches zero, it invokes the original callback with the
* provided arguments and clears the interval.
*
* If the timeout is within the maximum limit, it falls back to using the
* standard setTimeout.
*
* @author jimmy warting
* @param {(...rest) => void} callback
* @param {number} timeout
* @returns {number}
*/
function setLongTimeout (callback, timeout, ...args) {
const maxDelay = 2 ** 31 - 1
if (timeout > maxDelay) {
let expectedTicks = Math.ceil(timeout / maxDelay)
const id = setInterval(() => {
if (!--expectedTicks) {
callback(...args)
clearInterval(id)
}
}, timeout / expectedTicks)
return id
}
// If the delay is within the maximum limit, use regular setTimeout
return setTimeout(callback, timeout, ...args)
}
console.time('setLongTimeout')
// Usage example with additional arguments
const timeoutId = setLongTimeout(function(foo, bar) {
console.timeEnd('setLongTimeout')
}, 1500, 'Hello, world!', 123);
it will only create one singe timerID so it dose not have to create any custom class with dynamically updated id or custom clear function. clearTimeout(timeoutId)
works just fine on interval timer as well.
here is a much sorter version:
function setLongTimeout (callback, t, ...args) {
let i = Math.ceil(t / 2 ** 31 - 1),
id = setInterval(() => {
--i || clearInterval(id, callback(...args))
}, t / i)
return id
}