admin管理员组文章数量:1134589
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?
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?
Share Improve this question asked Aug 12, 2010 at 14:13 Matt BallMatt Ball 360k102 gold badges652 silver badges719 bronze badges 1- 1 Because it's limited to 32-bit, which is 2 power 32. If you calculate it you get 4294967296. Now, you need the first bit to decide whether it is a negative or positive number. So you get 2 power 31 and you get half of 4294967296, which is 2147483648. But zero is a positive number so 2147483647. – Joe Commented Jan 21, 2021 at 11:10
7 Answers
Reset to default 183This 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.
You can use:
const MAX_INT32 = 2 ** 31 - 1; // 2147483647 (hex 0x7FFFFFFF)
function runAtDate(date, func) {
const now = Date.now();
const then = date.valueOf();
const diff = Math.max(then - now, 0);
if (diff > MAX_INT32) {
setTimeout(() => {
runAtDate(date, func, MAX_INT32);
}, MAX_INT32);
} else {
setTimeout(func, diff);
}
}
Or, a slightly more involved version that allows you to clear the timeout using the returned value:
const MAX_INT32 = 2 ** 31 - 1;
function runAtDate(date, func, msPerTimeout = MAX_INT32) {
const timeout = arguments[3] ?? { valueOf() { return this._val; } };
const now = Date.now();
const then = date.valueOf();
const diff = Math.max(then - now, 0);
if (diff > msPerTimeout) {
timeout._val = setTimeout(() => {
runAtDate(date, func, msPerTimeout, timeout);
}, msPerTimeout);
} else {
timeout._val = setTimeout(func, diff);
}
return timeout
}
// Usage (using a much lower `msPerTimeout` value for demo purposes)
void (async () => {
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
// v1 (running to completion)
{
const timeout = runAtDate(
Date.now() + 1000,
() => console.log('v1 done!
本文标签:
javascriptWhy does setTimeout() quotbreakquot for large millisecond delay valuesStack Overflow
版权声明:本文标题:javascript - Why does setTimeout() "break" for large millisecond delay values? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人,
转载请联系作者并注明出处:http://www.betaflare.com/web/1736806963a1953729.html,
本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论