Why does setTimeout() "break" for large millisecond delay values?
I came across some unexpected behavior when passing a large millisecond value to setTimeout()
. For instance,
setTimeout(some_callback, Number.MAX_VALUE);
and
setTimeout(some_callback, Infinity);
both cause some_callback
to be run almost immediately, as if I'd passed 0
instead of a large number as the delay.
Why does this happen?
Solution 1:
This is due to setTimeout using a 32 bit int to store the delay so the max value allowed would be
2147483647
if you try
2147483648
you get your problem occurring.
I can only presume this is causing some form of internal exception in the JS Engine and causing the function to fire immediately rather than not at all.
Solution 2:
You can use:
function runAtDate(date, func) {
var now = (new Date()).getTime();
var then = date.getTime();
var diff = Math.max((then - now), 0);
if (diff > 0x7FFFFFFF) //setTimeout limit is MAX_INT32=(2^31-1)
setTimeout(function() {runAtDate(date, func);}, 0x7FFFFFFF);
else
setTimeout(func, diff);
}
Solution 3:
Some explanation here: http://closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
Timeout values too big to fit into a signed 32-bit integer may cause overflow in FF, Safari, and Chrome, resulting in the timeout being scheduled immediately. It makes more sense simply not to schedule these timeouts, since 24.8 days is beyond a reasonable expectation for the browser to stay open.