问题
如果delay
超过 2147483648 毫秒(24.8551 天),该函数将立即触发。
例子
setTimeout(function(){ console.log('hey') }, 2147483648) // this fires early
setTimeout(function(){ console.log('hey') }, 2147483647) // this works properly
我在 Chrome v26 和 Node.js v8.21 下试过
如果delay
超过 2147483648 毫秒(24.8551 天),该函数将立即触发。
setTimeout(function(){ console.log('hey') }, 2147483648) // this fires early
setTimeout(function(){ console.log('hey') }, 2147483647) // this works properly
我在 Chrome v26 和 Node.js v8.21 下试过
setTimeout 的上限为0x7FFFFFFF
(或2147483647
十进制)
这是因为 setTimeout 使用一个 32 位整数来存储它的延迟值,所以任何高于此值都会导致问题
如果您想要在 X 天后触发的超时,您可以尝试使用setInterval
像这样的较低延迟值
function setDaysTimeout(callback,days) {
// 86400 seconds in a day
var msInDay = 86400*1000;
var dayCount = 0;
var timer = setInterval(function() {
dayCount++; // a day has passed
if(dayCount == days) {
clearInterval(timer);
callback.apply(this,[]);
}
},msInDay);
}
然后你会像这样使用它
setDaysTimeout(function() {
console.log('Four days gone');
},4); // fire after 4 days
由于您仅限于 32 位,因此只需将 setTimeout 包装在递归函数中,如下所示:
function setLongTimeout(callback, timeout_ms)
{
//if we have to wait more than max time, need to recursively call this function again
if(timeout_ms > 2147483647)
{ //now wait until the max wait time passes then call this function again with
//requested wait - max wait we just did, make sure and pass callback
setTimeout(function(){ setLongTimeout(callback, (timeout_ms - 2147483647)); },
2147483647);
}
else //if we are asking to wait less than max, finally just do regular setTimeout and call callback
{ setTimeout(callback, timeout_ms); }
}
这并不太复杂,应该可以扩展到 1.7976931348623157E+10308 的 javascript 数字的限制,到那个毫秒数,我们都将死去。
也可以这样做,以便您能够设置LongTimeout,您可以修改函数以接受通过引用传递的对象,从而将范围保留回调用函数:
function setLongTimeout(callback, timeout_ms, timeoutHandleObject)
{
//if we have to wait more than max time, need to recursively call this function again
if(timeout_ms > 2147483647)
{ //now wait until the max wait time passes then call this function again with
//requested wait - max wait we just did, make sure and pass callback
timeoutHandleObject.timeoutHandle = setTimeout(function(){ setLongTimeout(callback, (timeout_ms - 2147483647), timeoutHandleObject); },
2147483647);
}
else //if we are asking to wait less than max, finally just do regular setTimeout and call callback
{ timeoutHandleObject.timeoutHandle = setTimeout(callback, timeout_ms); }
}
现在您可以调用超时,然后在需要时取消它,如下所示:
var timeoutHandleObject = {};
setLongTimeout(function(){ console.log("Made it!");}, 2147483649, timeoutHandleObject);
setTimeout(function(){ clearTimeout(timeoutHandleObject.timeoutHandle); }, 5000);