为什么setTimeout()在大的毫秒延迟值中“打破”?
当传递一个大的毫秒值给setTimeout()
时,我遇到了一些意想不到的行为。 例如,
setTimeout(some_callback, Number.MAX_VALUE);
和
setTimeout(some_callback, Infinity);
都导致几乎立即运行some_callback
,就好像我已经通过了0
而不是一个大数字作为延迟。
为什么会发生?
这是由于setTimeout使用32位int来存储延迟,所以允许的最大值将是
2147483647
如果你尝试
2147483648
你会发生你的问题。
我只能认为这是在JS引擎中引起某种forms的内部exception,导致函数立即启动而不是根本不启动。
这里有一些解释: http : //closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
超时值太大而无法放入带符号的32位整数,可能会导致FF,Safari和Chrome中出现溢出,导致立即计划超时。 更简单的是不安排这些超时,因为24.8天超出浏览器保持开放的合理预期。
您可以使用:
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); }
Number.MAX_VALUE
实际上不是一个整数。 setTimeout的最大允许值可能是2 ^ 31或2 ^ 32。 尝试
parseInt(Number.MAX_VALUE)
你拿回1而不是1.7976931348623157e + 308。