Was passiert mit setTimeout, wenn der Computer in den Ruhezustand wechselt?

Lesezeit: 2 Minuten

Benutzer-Avatar
Sudhir Jonathan

Angenommen, ich mache in einem modernen Webbrowser a setTimeout für 10 Minuten (um 12:00) und 5 Minuten später den Computer in den Ruhezustand versetzen, was soll passieren, wenn das System wieder aufwacht? Was passiert, wenn es aufwacht, bevor die 10 Minuten abgelaufen sind (um 12:09) oder viel später (um 16:00)?

Der Grund, warum ich frage, ist, dass ich möchte, dass alle 10 Minuten ein neues Authentifizierungstoken angefordert wird, und ich bin mir nicht sicher, ob der Browser das Richtige tut und sofort ein neues Token anfordert, wenn er nach langer Zeit aufwacht Zeit.

Erläuterungen: Ich möchte keine Cookies verwenden – ich versuche hier einen Webservice aufzubauen; und ja, der Server wird alte und ungültige Token ablehnen.

  • Da Javascript clientseitig ist, wäre es nicht besser, ein Cookie zu setzen, das zu einem bestimmten Zeitpunkt ablaufen kann?

    – Tagesanbruch

    14. Juni 2011 um 16:32 Uhr

  • stackoverflow.com/questions/3824754/… schlägt vor, wie Andrew antwortete, dass es nicht funktionieren wird.

    – Sysyphos

    14. Juni 2011 um 16:39 Uhr

  • @daybreaker, Sicher sind Cookies möglich, aber ich versuche, eine dienstbasierte App zu erstellen. Dieselben Dienste dienen der Web-App, iPhone- und Android-App.

    – Sudhir Jonathan

    14. Juni 2011 um 19:32 Uhr


Benutzer-Avatar
KooiInc

Soweit ich getestet habe, stoppt es einfach und wird fortgesetzt, nachdem der Computer aufgewacht ist. Wenn der Computer aufwacht, weiß setInterval/setTimeout nicht, dass Zeit vergangen ist.

Ich denke nicht, dass Sie sich auf die Genauigkeit von verlassen sollten setTimeout/Interval für zeitkritische Sachen. Für Google Chrome habe ich kürzlich festgestellt, dass jedes Timeout/Intervall (das kürzer als 1 s ist) auf einmal pro Sekunde verlangsamt wird, wenn der Tab, auf dem es aktiviert ist, den Fokus verliert.

Abgesehen davon ist die Genauigkeit von Timeouts/Intervallen abhängig von anderen laufenden Funktionen usw. Kurz gesagt: es ist nicht sehr genau.

Wenn Sie also Intervalle und Zeitüberschreitungen verwenden und die Zeit mit einer Startzeit innerhalb der von ihr gestarteten Funktion vergleichen, erhalten Sie eine bessere Genauigkeit. Wenn Sie jetzt um 12:00 Uhr starten, geht der Computer in den Ruhezustand und wacht um 16:13 Uhr oder so auf, und wenn Sie 16:13 Uhr gegen 12:00 Uhr prüfen, sind Sie sicher, dass Sie das Token erneuern müssen. Ein Beispiel für die Verwendung des Zeitvergleichs finden Sie hier hier

  • Das deckt sich auch mit meiner Erfahrung.

    – jwl

    11. Januar 2012 um 16:48 Uhr

  • Dazu habe ich gerade einen Schnelltest erstellt. FF 30 und Chrome 35 leisten eine angemessene Arbeit, indem sie das lang andauernde Timeout auslösen, sobald der Computer fortgesetzt wird. IE 10 lädt die Seite neu. Geige @ jsfiddle.net/Pegleg3941/8uhy8

    – Epische Reise

    3. Juli 2014 um 15:29 Uhr

  • the counter ticks on from the time the computer fell asleep.<- auch meine Erfahrung.

    – Mahn

    26. November 2014 um 17:12 Uhr

  • Ab 2017 (Chrome 61) hat sich dieses Verhalten des Fortsetzens des Zählers vom Einschlafen nicht geändert.

    – Erez Cohen

    17. Oktober 2017 um 10:47 Uhr

  • Ich denke, dies könnte klarer formuliert werden: Wenn der Computer aufwacht, weiß setInterval/setTimeout nicht, dass irgendeine Zeit vergangen ist.

    – cdosborn

    18. Dezember 2019 um 19:24 Uhr

Vergleichen Sie die aktuelle Datumszeit mit der Datumszeit, als die Seite geladen wurde, wie folgt:

//Force refresh after x minutes.
var initialTime = new Date();
var checkSessionTimeout = function () {
    var minutes = Math.abs((initialTime - new Date()) / 1000 / 60);
    if (minutes > 20) {
        setInterval(function () { location.href="https://stackoverflow.com/questions/6346849/Audit.aspx" }, 5000)
    } 
};
setInterval(checkSessionTimeout, 1000);

  • Dies ist eine großartige Lösung. Funktioniert bei mir sehr gut – danke.

    – BeesonBison

    28. Juni 2016 um 8:26 Uhr

  • In meinem Fall muss ich nur dann ein neues Token erhalten, wenn der Benutzer in der letzten Stunde aktiv und nicht im Leerlauf ist. Also vom Server-Token mit Ablauf nach 1 Stunde, aber vorher muss ich ein neues bekommen und localStorage aktualisieren. Wenn der Benutzer inaktiv ist, wird die Nachricht „Sitzung abgelaufen“ angezeigt, andernfalls erhalten Sie stillschweigend ein neues Token

    – CyberAbhay

    14. Mai 2019 um 12:09 Uhr

  • Was ist der Grund für das innere setInterval()? Warum 5 Sekunden?

    – robsch

    14. Januar 2020 um 13:18 Uhr

Benutzer-Avatar
DannyBoi

Hier ist mein Code:

<!doctype html>
<html>

<body>
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 120000)"/>

</body>
<script>


</script>
</html>

Ich habe drei Szenarien genommen, die die Frage beantworten könnten.

Szenario 1: Klicken Sie bei 00 Sekunden auf die Schaltfläche „Timer starten“ . Nach 25 Sekunden schläft der Computer ein. Bei 1min 40 Sekunden Computer aufwecken. Bei 2 Minuten wird ein Alarm angezeigt.

Szenario 2: Klicken Sie bei 00 Sekunden auf die Schaltfläche „Timer starten“ . Bei 26 Sekunden schläft der Computer ein. Bei 3 Minuten wecke ich den Computer auf. Die Warnung wird angezeigt.

Szenario 3: Dieser ist wirklich erstaunlich.

<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 600000)"/>

Bei 00 Sekunden klicke ich auf die Schaltfläche „Start Timer“. Nach etwa 1 Minute 30 Sekunden befindet sich der Computer im Ruhezustand (mein PC braucht eine Minute, um den Ruhezustand einzuleiten).

Bei 8 Minuten schalte ich den Laptop ein. Genau nach 10 Minuten erscheint die Warnung.

PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.

Benutzer-Avatar
Andreas Kurioso

Das Verhalten basiert sowohl auf dem Browser als auch auf dem Betriebssystem. Das Betriebssystem verwaltet den Ruhezustand und einzelne Apps berücksichtigen dies häufig nicht.

Was höchstwahrscheinlich passieren wird, ist, dass das Betriebssystem mit der gleichen verbleibenden Zeit auf dem Timer wie beim Herunterfahren wieder hochfährt. Die andere Möglichkeit ist, dass es überhaupt nicht zündet.

Wenn es wirklich ein Problem ist, möchten Sie wahrscheinlich besser auf Nummer sicher gehen und einen Zeitstempel speichern, wann das Token initialisiert und verwendet wurde setInterval um es regelmäßig zu überprüfen (z. B. zweimal pro Minute).

Sicherheit sollte jedoch nicht nur eine Sache des Clients sein. Stellen Sie sicher, dass Ihr Server einen Fehler auslöst, wenn ein alter/ungültiger Token verwendet wird, und dass sich Ajax entsprechend verhält.

[edit]

Ich stimme dem anderen Beitrag zu, dass es beim nächsten Tick sofort ausgelöst werden könnte. Resigs Blogbeitrag ist sehr gut.

Basierend auf Bens Antwort habe ich das folgende Dienstprogramm erstellt. Sie können die Sampling-Dauer anpassen, aber ich verwende sie einfach so für die Token-Aktualisierung:

const absoluteSetInterval = (handler, timeout) => {
  let baseTime = Date.now();
  const callHandler = () => {
    if (Date.now() - baseTime > timeout) {
      baseTime = Date.now();
      handler();
    }
  };
  return window.setInterval(callHandler, 1000);
};

const absoluteClearInterval = (handle) => window.clearInterval(handle);

Verhalten von JavaScript-Timern (setTimeout) in mehreren Szenarien.

  1. Wenn der Thread frei ist und das Timeout ausgelöst wird: Der Timer wird unmittelbar nach dem Timeout ausgelöst. Es kann eine gewisse Ungenauigkeit von etwa 0-5 ms haben (typisches Szenario).
  2. Wenn der Thread lange genug überlastet ist (große Schleife), um das Zeitlimit des Timers zu überschreiten: Der Timer wird sofort ausgeführt, nachdem der Thread freigegeben wurde.
  3. Bei Alarm: Gleiches Verhalten wie 2.
  4. Wenn der Thread pausiert, weil unser Laptop eingeschlafen ist: Ich habe mehrere Dinge gesehen. Am häufigsten ist jedoch die völlige Ungenauigkeit und das Ignorieren der Zeit, die während des Schlafens verbracht wird.

Da Timer in JavaScript auf CPU-Ticks basieren und die CPU schläft, wird der Timer vollständig angehalten und fortgesetzt, da “da nichts passiert wäre”.

Benutzer-Avatar
Jewgeni Schadtschnew

Im John Resigs Blog Die Timer sollen “Wanduhr” verwenden. Ich glaube, dass die Ereignisse sofort nach dem Neustart der Maschine ausgelöst werden, da setTimeout() nicht garantiert, dass eine Ausführung zu einem bestimmten Zeitpunkt erfolgt, sondern so bald wie möglich nach dem angegebenen Intervall. Allerdings habe ich es selbst nicht überprüft.

  • Sie hätten es überprüfen sollen – so funktioniert es nicht, und Ihre Schlussfolgerung auf der Grundlage von JRs Blog ist sehr locker. Es folgt definitiv nicht der Wanduhr auf irgendeinem System, auf dem ich getestet habe.

    – jwl

    11. Januar 2012 um 16:48 Uhr

  • FWIW, die Spezifikation sagt Folgendes: „Warten Sie, bis das dem Methodenkontext zugeordnete Dokument für eine weitere Zeitüberschreitung in Millisekunden vollständig aktiv war (nicht unbedingt hintereinander)”. Das impliziert, dass der Timer ausgesetzt werden könnte, während der Computer im Ruhezustand ist.

    – geon

    2. September 2014 um 6:57 Uhr


1158550cookie-checkWas passiert mit setTimeout, wenn der Computer in den Ruhezustand wechselt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy