Ich bin auf ein unerwartetes Verhalten gestoßen, als ich einen großen Millisekundenwert an übergeben habe setTimeout()
. Zum Beispiel,
setTimeout(some_callback, Number.MAX_VALUE);
und
setTimeout(some_callback, Infinity);
beide führen some_callback
dazu, dass sie fast sofort ausgeführt werden, als hätte ich 0
anstelle einer großen Zahl die Verzögerung überschritten .
Warum passiert das?
javascript
settimeout
Matt Ball
quelle
quelle
delay >>> 0
passiert so etwas wie , so dass die verstrichene Verzögerung Null ist. In jedem Fall erklärt die Tatsache, dass die Verzögerung als 32-Bit-Int ohne Vorzeichen gespeichert ist, dieses Verhalten. Vielen Dank!49999861776383
(49999861776384
bewirkt, dass der Rückruf sofort49999861776383 % 2147483648 === 2147483647
Sie können verwenden:
quelle
Einige Erklärungen hier: http://closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
quelle
setTimeout()
, aber ich würde hoffen, dass sie das Datum und die Uhrzeit berechnen, zu der es aufwachen sollte, und keinen Zähler auf einem zufällig definierten Tick dekrementieren ... (Man kann hoffen , zumindest)Schauen Sie sich das Knotendokument zu Timern hier an: https://nodejs.org/api/timers.html (vorausgesetzt, dass dies auch für js gilt, da es sich derzeit um einen so allgegenwärtigen Begriff handelt, der auf Ereignisschleifen basiert
Zusamenfassend:
Wenn die Verzögerung größer als 2147483647 oder kleiner als 1 ist, wird die Verzögerung auf 1 gesetzt.
und Verzögerung ist:
Die Anzahl der Millisekunden, die gewartet werden muss, bevor der Rückruf aufgerufen wird.
Scheint, als würde Ihr Timeout-Wert nach diesen Regeln standardmäßig auf einen unerwarteten Wert gesetzt, möglicherweise?
quelle
Ich bin darauf gestoßen, als ich versucht habe, einen Benutzer mit einer abgelaufenen Sitzung automatisch abzumelden. Meine Lösung bestand darin, das Timeout nach einem Tag zurückzusetzen und die Funktionalität für die Verwendung von clearTimeout beizubehalten.
Hier ist ein kleines Prototypbeispiel:
Verwendung:
Und Sie können es mit der
stopTimer
Methode löschen :quelle
Ich kann nicht kommentieren, aber um allen Leuten zu antworten. Es nimmt einen vorzeichenlosen Wert an (Sie können offensichtlich keine negativen Millisekunden abwarten). Da der maximale Wert also "2147483647" ist, wenn Sie einen höheren Wert eingeben, beginnt er bei 0.
Grundsätzlich Verzögerung = {VALUE}% 2147483647.
Die Verwendung einer Verzögerung von 2147483648 würde also 1 Millisekunde ergeben, daher sofortiger Prozess.
quelle
ist eigentlich keine ganze Zahl. Der maximal zulässige Wert für setTimeout beträgt wahrscheinlich 2 ^ 31 oder 2 ^ 32. Versuchen
und Sie erhalten 1 zurück statt 1.7976931348623157e + 308.
quelle
Number.MAX_VALUE
ist eine Ganzzahl. Es ist die Ganzzahl 17976931348623157 mit 292 Nullen danach. Der Grund , warumparseInt
kehrt1
, weil sie erst in einen String sein Argument konvertiert und sucht dann die Zeichenfolge von links nach rechts. Sobald es das findet.
(was keine Zahl ist), stoppt es.Number.isInteger(foo)
. Da es jedoch noch nicht unterstützt wird, können Sie esMath.round(foo) === foo
stattdessen verwenden.Number.MAX_VALUE
keine Ganzzahl, sondern einedouble
. Es gibt also Folgendes: Ein Double kann jedoch eine Ganzzahl darstellen, da es zum Speichern von Ganzzahlen mit 32 Bit in JavaScript verwendet wird.Number.MAX_VALUE
ist, handelt es sich nicht um eine Ganzzahl. Aber wenn Sie mit "Ganzzahl" das mentale Konzept einer "Ganzzahl" meinen, dann ist es eine Ganzzahl. In JavaScript wird häufig die mentale Konzeptdefinition "Ganzzahl" verwendet, da alle Zahlen 64-Bit-Gleitkommazahlen sind.Number.MAX_SAFE_INTEGER
aber das ist auch nicht die Nummer, nach der wir hier suchen.