Je suis tombé sur un comportement inattendu en passant une valeur importante en millisecondes à setTimeout()
. Par exemple,
setTimeout(some_callback, Number.MAX_VALUE);
et
setTimeout(some_callback, Infinity);
les deux causent some_callback
d'être exécutés presque immédiatement, comme si j'avais passé 0
au lieu d'un grand nombre comme retard.
Pourquoi cela arrive-t-il?
javascript
settimeout
Matt Ball
la source
la source
delay >>> 0
se produit, donc le délai passé est nul. Dans tous les cas, le fait que le délai soit stocké sous la forme d'un int non signé 32 bits explique ce comportement. Merci!49999861776383
(49999861776384
provoque le déclenchement instantané du rappel)49999861776383 % 2147483648 === 2147483647
Vous pouvez utiliser:
la source
Quelques explications ici: http://closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
la source
setTimeout()
, mais j'espère qu'ils calculent la date et l'heure à laquelle il devrait se réveiller et ne décrémentent pas un compteur sur un tick défini au hasard ... (On peut espérer , au moins)Consultez la documentation des nœuds sur les minuteries ici: https://nodejs.org/api/timers.html (en supposant la même chose pour js car c'est un terme tellement omniprésent maintenant basé sur une boucle d'événements
En bref:
Lorsque le délai est supérieur à 2147483647 ou inférieur à 1, le délai sera réglé sur 1.
et le retard est:
Le nombre de millisecondes à attendre avant d'appeler le rappel.
Il semble que votre valeur de délai d'expiration soit réglée par défaut sur une valeur inattendue selon ces règles, peut-être?
la source
Je suis tombé sur cela lorsque j'ai essayé de déconnecter automatiquement un utilisateur avec une session expirée. Ma solution était de simplement réinitialiser le délai d'expiration après un jour et de conserver la fonctionnalité permettant d'utiliser clearTimeout.
Voici un petit exemple de prototype:
Usage:
Et vous pouvez l'effacer avec la
stopTimer
méthode:la source
Je ne peux pas faire de commentaire mais répondre à tout le monde. Cela prend une valeur non signée (vous ne pouvez pas attendre des millisecondes négatives évidemment) Donc, comme la valeur maximale est "2147483647" lorsque vous entrez une valeur plus élevée, elle commence à partir de 0.
En gros, retard = {VALUE}% 2147483647.
Donc, utiliser un délai de 2147483648 équivaudrait à 1 milliseconde, donc instant proc.
la source
n'est en fait pas un entier. La valeur maximale autorisée pour setTimeout est probablement 2 ^ 31 ou 2 ^ 32. Essayer
et vous obtenez 1 en retour au lieu de 1.7976931348623157e + 308.
la source
Number.MAX_VALUE
est un entier. C'est le nombre entier 17976931348623157 suivi de 292 zéros. La raison estparseInt
renvoyée1
parce qu'il convertit d'abord son argument en chaîne, puis recherche la chaîne de gauche à droite. Dès qu'il trouve le.
(qui n'est pas un nombre), il s'arrête.Number.isInteger(foo)
. Mais comme il n'est pas encore pris en charge, vous pouvez utiliser à laMath.round(foo) === foo
place.Number.MAX_VALUE
n'est pas un entier mais undouble
. Donc il y a ça ... Un double peut représenter un entier, cependant, car il est utilisé pour sauvegarder des entiers de 32 bits en JavaScript.Number.MAX_VALUE
n'est pas un entier. Mais si par "entier" vous entendez le concept mental "d'un entier", alors c'est un entier. En JavaScript, comme tous les nombres sont à virgule flottante 64 bits, il est courant d'utiliser la définition du concept mental d '«entier».Number.MAX_SAFE_INTEGER
mais ce n'est pas le nombre que nous recherchons ici non plus.