Récemment, j'ai découvert un pistolet à pied dans la vraie vie, qui était lié à setTimeout, j'ai dû exécuter un délai d'attente pendant, disons, 28 jours pour un minuteur de vente, j'avais un horodatage UTC pour la fin jour, donc avec une approche naïve, j'ai fait ça
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);
À ma grande surprise, cela n'a pas fonctionné ou a trop bien fonctionné, puisque le code de setTimeout s'est exécuté sans attendre le délai d'attente, j'ai décidé de déboguer dans le navigateur et j'ai vu que le contrôle sautait presque instantanément dans le rappel setTimeout.
En regardant la page MDN de setTimeout, https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value , il était clair qu'il y avait une limite maximale jusqu'à laquelle setTimeout() s'exécuterait avec précision, spécifiquement
2 147 483 647 ms ou (24,8 jours) ou (2**31 - 1) ms, cela est dû au fait que les navigateurs stockent le délai sous la forme d'un entier signé de 32 bits en interne.
Ainsi, à chaque fois que vous dépassez un timeout de plus de 24,8 jours, il y a un débordement d'entier et le code est exécuté immédiatement ou plutôt avec une durée de timeout inférieure à celle prévue. C'est dommage, et il n'y a pas d'erreur !!!
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);
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!