WebKit setInterval und Systemzeit ändern

8

Ich habe folgendes Problem beim Erstellen einer einfachen Aufgabe festgestellt: Anzeige der HTML-Uhr mit der WebKit-Engine. Eine zusätzliche Anforderung bestand darin, die Systemzeit zu ändern und dass es unter Windows funktionieren sollte. Ich habe setInterval verwendet, um dies zu erreichen, aber es scheint Browser einzufrieren, nachdem ich die Systemzeit rückwärts geändert habe. Für mich sieht es wie WebKit aus. Es ist einfach, auf Safari mit diesem einfachen Code zu reproduzieren:

%Vor%

Danach habe ich einen weiteren Ansatz mit rekursivem setTimeout-Aufruf gemacht. Gleicher Effekt.

%Vor%

Irgendwelche Ideen, warum passiert das und wie geht das um?

    
Sleipnir 11.04.2014, 13:01
quelle

1 Antwort

2

Dies ist fast definitiv ein Problem mit WebKit.

Das Problem

Wenn Sie setTimeout verwenden, erstellen Sie einen 'Timer' mit zwei Eigenschaften:

  • Ein Zeitstempel , jetzt auf + die angegebene Verzögerung gesetzt
  • Ein Callback , der einmal ausgelöst wird, sobald die Systemzeit größer als der Zeitstempel ist.

Sie können sich eine naive Implementierung von setTimeout vorstellen, die etwa so aussieht:

%Vor%

Dies würde einfach einen Timer erstellen und ihn einer Liste hinzufügen. Dann prüft die JS-Laufzeit bei jedem Tick diese Timer und führt die Callbacks für diejenigen aus, die gefeuert haben:

%Vor%

Stellen Sie sich jetzt vor, dass Sie die Systemzeit (dh Date.now() in den obigen Beispielen) auf einen Wert in der Vergangenheit ändern - der Zeitstempel des Timers wird immer noch relativ zur vorherigen Systemzeit gesetzt (dh in der Zukunft) .

Das gleiche Problem existiert mit setInterval , das (unter der Annahme, dass es sich um normalen Code in WebKit handelt) mit setTimeout implementiert wird.

Leider bedeutet dies, dass der beliebige Aufruf von setTimeout oder setInterval leiden wird.

Die Lösung

Als Alternative können Sie die schöne Methode window.requestAnimationFrame ausführen ein Rückruf bei jedem Tick. Ich habe das gar nicht getestet, aber es sollte weiterhin bei jedem Tick brennen, unabhängig von der Systemzeit.

Als Bonus wird jedes Mal, wenn der Callback ausgelöst wird, der aktuelle Zeitstempel als Parameter übergeben. Wenn Sie den früheren Zeitstempel, der an Ihren Rückruf übergeben wurde, im Auge behalten, können Sie Änderungen der Systemzeit rückwärts leicht erkennen:

%Vor%

Schlussfolgerungen

Das sind vielleicht keine guten Nachrichten für Sie, aber Sie sollten Ihre gesamte Anwendung wahrscheinlich neu schreiben, um requestAnimationFrame trotzdem zu verwenden - es scheint viel besser zu Ihren Bedürfnissen zu passen:

%Vor%     
Jim O'Brien 16.04.2014, 10:18
quelle

Tags und Links