141 votes

Pourquoi setTimeout() "s'arrête" pour les grandes valeurs de délai en millisecondes ?

Je suis tombé sur un comportement inattendu en passant une grande valeur de milliseconde à setTimeout() . Par exemple,

setTimeout(some_callback, Number.MAX_VALUE);

y

setTimeout(some_callback, Infinity);

les deux causent some_callback pour être exécuté presque immédiatement, comme si j'avais passé 0 au lieu d'un grand nombre comme le délai.

Pourquoi cela se produit-il ?

1 votes

Parce que c'est limité à 32 bits, ce qui est 2 puissance 32. Si vous le calculez, vous obtenez 4294967296. Maintenant, vous avez besoin du premier bit pour décider si c'est un nombre négatif ou positif. On obtient donc 2 puissance 31 et la moitié de 4294967296, soit 2147483648. Mais zéro est un nombre positif, donc 2147483647.

1voto

KYGAS Points 11

Je ne peux pas faire de commentaire mais je vais répondre à toutes les personnes. Il prend une valeur non signée (vous ne pouvez pas attendre des millisecondes négatives évidemment). Donc, puisque la valeur maximale est "2147483647", lorsque vous entrez une valeur supérieure, il commence à partir de 0.

En gros, le délai = {VALEUR} % 2147483647.

Donc, en utilisant un délai de 2147483648, cela ferait 1 milliseconde, donc une proc instantanée.

-3voto

Osmund Points 271
Number.MAX_VALUE

n'est en fait pas un nombre entier. La valeur maximale autorisée pour setTimeout est probablement 2^31 ou 2^32. Essayez

parseInt(Number.MAX_VALUE) 

et vous récupérez 1 au lieu de 1,7976931348623157e+308.

13 votes

Ceci est incorrect : Number.MAX_VALUE est un nombre entier. C'est le nombre entier 17976931348623157 avec 292 zéros après. La raison parseInt renvoie à 1 est parce qu'il convertit d'abord son argument en une chaîne de caractères, puis recherche la chaîne de gauche à droite. Dès qu'elle trouve le . (qui n'est pas un nombre), il s'arrête.

1 votes

Au fait, si vous voulez tester si quelque chose est un nombre entier, utilisez la fonction ES6 Number.isInteger(foo) . Mais comme il n'est pas encore supporté, vous pouvez utiliser Math.round(foo) === foo à la place.

2 votes

@Pauan, en ce qui concerne la mise en œuvre, Number.MAX_VALUE n'est pas un nombre entier mais un double . Il y a donc ça... Un double peut cependant représenter un entier, puisqu'il est utilisé pour enregistrer des entiers de 32 bits en JavaScript.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X