如果延迟超过2147483648毫秒,setTimeout立即触发
问题
如果delay
超过2147483648毫秒(24.8551天),该function将立即触发。
例
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位,所以只需在一个recursion函数中包装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); } }
这不是太复杂,应该可以扩展到JavaScript数量的限制,即1.7976931348623157E + 10308,这个毫秒数量,我们都将死去。
太使它成为你可以设置LongTimeout的能力,你可以修改函数来接受一个通过引用传递的对象,从而将范围保留callback用函数:
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);