Rumah > hujung hadapan web > tutorial js > setTimeout - senapang kaki tamat masa maksimum

setTimeout - senapang kaki tamat masa maksimum

Linda Hamilton
Lepaskan: 2024-11-23 16:48:21
asal
856 orang telah melayarinya

setTimeout - max timeout footgun

Baru-baru ini saya menemui senapang kaki dalam kehidupan sebenar, yang berkaitan dengan setTimeout, saya terpaksa menjalankan tamat masa untuk katakan 28 hari untuk pemasa jualan, saya mempunyai cap waktu UTC untuk penghujungnya hari, jadi dengan pendekatan naif, saya melakukan ini

 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);
Salin selepas log masuk

Saya terkejut, ini tidak berfungsi atau berfungsi dengan baik, kerana kod dalam setTimeout dilaksanakan tanpa menunggu tamat masa, saya memutuskan untuk nyahpepijat dalam penyemak imbas, dan saya melihat bahawa kawalan melompat ke dalam panggilan balik setTimeout hampir serta-merta.

Apa masalah di sini?

Melihat halaman MDN setTimeout, https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value , adalah jelas bahawa terdapat had maksimum sehingga setTimeout() akan dijalankan dengan tepat, khususnya
2,147,483,647ms atau (24.8 hari) atau (2**31 - 1) ms, ini kerana penyemak imbas menyimpan kelewatan sebagai integer bertanda 32-bit secara dalaman.

Jadi apabila anda melepasi tamat masa lebih daripada 24.8 hari, terdapat limpahan integer dan kod dilaksanakan serta-merta atau lebih tepat dengan tempoh tamat masa yang lebih rendah daripada yang dijangkakan. Itu mengecewakan, dan tiada ralat !!!

Penyelesaian yang mungkin untuk masalah ini

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);

Salin selepas log masuk

Atas ialah kandungan terperinci setTimeout - senapang kaki tamat masa maksimum. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan