首頁 > web前端 > js教程 > 主體

setTimeout - 最大超時 footgun

Linda Hamilton
發布: 2024-11-23 16:48:21
原創
770 人瀏覽過

setTimeout - max timeout 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中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板