Answers:
这是由于setTimeout使用32位int存储延迟,因此允许的最大值为
2147483647
如果你试试
2147483648
您会遇到问题。
我只能假定这会导致JS Engine中某种形式的内部异常,并导致函数立即触发而不是根本不触发。
49999861776383
(49999861776384
导致回调立即触发)
49999861776383 % 2147483648 === 2147483647
您可以使用:
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);
}
此处提供一些解释:http : //closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
超时值太大而无法容纳带符号的32位整数,则可能会导致FF,Safari和Chrome浏览器溢出,从而导致立即安排超时。不安排这些超时时间更有意义,因为24.8天超出了浏览器保持打开状态的合理预期。
setTimeout()
,但是我希望他们能计算出它应该唤醒的日期和时间,并且不要在某个随机定义的刻度上递减计数器...(一个人可以希望,至少)
在此处查看有关Timers的节点文档:https : //nodejs.org/api/timers.html(假设在js中也是如此,因为在基于事件循环的环境中,它是一个无处不在的术语)
简而言之:
当延迟大于2147483647或小于1时,延迟将设置为1。
和延迟是:
调用回调之前要等待的毫秒数。
好像您的超时值按照这些规则被默认为意外值,可能吗?
当我尝试自动注销具有过期会话的用户时,我偶然发现了这一点。我的解决方案是在一天后重设超时,并保留使用clearTimeout的功能。
这是一个小的原型示例:
Timer = function(execTime, callback) {
if(!(execTime instanceof Date)) {
execTime = new Date(execTime);
}
this.execTime = execTime;
this.callback = callback;
this.init();
};
Timer.prototype = {
callback: null,
execTime: null,
_timeout : null,
/**
* Initialize and start timer
*/
init : function() {
this.checkTimer();
},
/**
* Get the time of the callback execution should happen
*/
getExecTime : function() {
return this.execTime;
},
/**
* Checks the current time with the execute time and executes callback accordingly
*/
checkTimer : function() {
clearTimeout(this._timeout);
var now = new Date();
var ms = this.getExecTime().getTime() - now.getTime();
/**
* Check if timer has expired
*/
if(ms <= 0) {
this.callback(this);
return false;
}
/**
* Check if ms is more than one day, then revered to one day
*/
var max = (86400 * 1000);
if(ms > max) {
ms = max;
}
/**
* Otherwise set timeout
*/
this._timeout = setTimeout(function(self) {
self.checkTimer();
}, ms, this);
},
/**
* Stops the timeout
*/
stopTimer : function() {
clearTimeout(this._timeout);
}
};
用法:
var timer = new Timer('2018-08-17 14:05:00', function() {
document.location.reload();
});
您可以使用以下stopTimer
方法清除它:
timer.stopTimer();
Number.MAX_VALUE
实际上不是整数。setTimeout的最大允许值可能是2 ^ 31或2 ^ 32。尝试
parseInt(Number.MAX_VALUE)
您会得到1而不是1.7976931348623157e + 308的回报。
Number.MAX_VALUE
是整数。它是整数17976931348623157,后面有292个零。parseInt
返回的原因1
是因为它首先将其参数转换为字符串,然后从左到右搜索字符串。一旦找到.
(不是数字),它将停止。
Number.isInteger(foo)
。但由于尚不支持,因此可以Math.round(foo) === foo
改用。
Number.MAX_VALUE
不是整数,而是a double
。因此,有一个... double可以表示一个整数,因为它用于在JavaScript中保存32位整数。
Number.MAX_VALUE
它不是整数。但是,如果用“整数”表示“整数”的心理概念,则它是整数。在JavaScript中,由于所有数字都是64位浮点,因此通常会使用“整数”的概念定义。
Number.MAX_SAFE_INTEGER
但这也不是我们在这里寻找的号码。
delay >>> 0
情况,因此所传递的延迟为零。无论哪种方式,延迟都存储为32位unsigned int的事实说明了这种现象。谢谢!