javascript - How long can NodeJS `setTimeout` wait? - Stack Overflow

admin2025-04-18  0

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?

Share Improve this question edited Nov 13, 2018 at 11:37 eisbehr 12.5k7 gold badges41 silver badges65 bronze badges asked Nov 13, 2018 at 11:36 McKabueMcKabue 2,2421 gold badge22 silver badges37 bronze badges 4
  • 1 It won't go to sleep, but there are better ways of doing that instead of setTimeout – baao Commented Nov 13, 2018 at 11:38
  • 2 This is technically possible, but there are definitely better ways of doing this e.g. cron job – James Commented Nov 13, 2018 at 11:42
  • If you want something done in an specific date you can use a cron library. The maximum setTimeout time must be defined, if not by other limitations, by the maximum integer JavaScript supports. – desoares Commented Nov 13, 2018 at 11:42
  • 1 @desoares the largest integer that JS supports is over 285,000 years... (counted in milliseconds) – Alnitak Commented Nov 13, 2018 at 11:58
Add a ment  | 

3 Answers 3

Reset to default 5

Answering your question

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)

Answering your use-case

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
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744969451a277398.html

最新回复(0)