
最近我在现实生活中发现了一个footgun,它与settimeout有关,我必须为销售计时器运行一个28天的超时,我有一个结束日期的utc时间戳,所以用天真的方法,我做了这个
const date1 = new date(timestamp1);
// difference in milliseconds
const timeout = date2.gettime() - date.now();
settimeout(()=>{
// some code to turn off some flags / remove some banner
},timeout);
令我惊讶的是,这并没有起作用或者效果太好,因为settimeout中的代码没有等待超时就执行了,我决定在浏览器中调试,我看到控件几乎立即跳转到settimeout回调中。
查看settimeout的mdn页面,https://developer.mozilla.org/en-us/docs/web/api/settimeout#maximum_delay_value,很明显settimeout()运行有一个最大限制准确地,具体地
2,147,483,647ms 或(24.8 天)或(2**31 - 1)ms,这是因为浏览器在内部将延迟存储为 32 位有符号整数。
因此,每当您传入超过 24.8 天的超时时,就会出现整数溢出,代码会立即执行,或者超时持续时间比预期短。太糟糕了,而且没有错误!!!
const days = 30;
const timeout = days * 24 * 60 * 60 * 1000;
console.log('timeto', timeout);
setTimeout(function () {
console.log('ticked immediately'); // --> executed almost instantly
}, timeout);
class LongTimeout {
constructor(cb, timeout) {
this.timeStart = document.timeline
? document.timeline.currentTime
: performance.now();
this.lastAnimationFrame = this.runTimer(cb, timeout);
}
runTimer(cb, timeout) {
if(this.cancelled) return;
const currTimeStamp = performance.now();
const elapsed = currTimeStamp - this.timeStart;
if (elapsed >= timeout) {
cb();
window.cancelAnimationFrame(this.lastAnimationFrame);
} else {
console.log('tick', elapsed, timeout);
this.lastAnimationFrame = requestAnimationFrame(() =>
this.runTimer(cb, timeout)
);
}
}
cancelTimeout() {
window.cancelAnimationFrame(this.lastAnimationFrame);
this.cancelled = true;
this.lastAnimationFrame = null;
}
}
const longTimer = new LongTimeout(() => {
console.log(`Tick after ${timeout}`); // timeout works -> does not execute immediately
}, timeout);
以上就是setTimeout - 最大超时 footgun的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号