mdn loop ejemplos javascript timer

loop - ¿Tiempo monótonamente creciente en JavaScript?



sleep javascript (4)

¿Cuál es la mejor manera de obtener un aumento monótono del tiempo en JavaScript? Estoy esperando algo como System.nanoTime() Java.

Date() obviamente no funcionará, ya que está afectada por los cambios de hora del sistema.

En otras palabras, lo que me gustaría es para a <= b, siempre :

a = myIncreasingTime.getMilliseconds(); ... // some time later, maybe seconds, maybe days b = myIncreasingTime.getMilliseconds();

En el mejor de los casos, incluso cuando se usan las funciones UTC en Date() , devolverá lo que cree que es la hora correcta, pero si alguien ajusta la hora hacia atrás, la próxima llamada a Fecha () puede devolver un valor menor. System.nanoTime() no sufre de esta limitación (al menos no hasta que se reinicie el sistema).

Modificación: [2012-02-26: no pretende afectar la pregunta original, que tiene una recompensa]

No estoy interesado en saber el "tiempo en la pared", estoy interesado en saber el tiempo transcurrido con cierta precisión, que Date() no puede proporcionar.


El propio Javascript no tiene ninguna funcionalidad para acceder a nanoTime. Es posible que cargue un applet de java para obtener esa información, como ha hecho benchmark.js . Tal vez @mathias pueda arrojar algo de luz sobre lo que hicieron allí ...


Firefox proporciona el argumento de "retraso" para setTimeout ... esta es una de las formas de implementar un contador de tiempo incrementado monótonamente.

var time = 0; setTimeout(function x(actualLateness) { setTimeout(x, 0); time += actualLateness; }, 0);


Podría usar window.performance.now() - desde Firefox 15, y window.performance.webkitNow () - Chrome 20]

var a = window.performance.now(); //... var delay = window.performance.now() - a;


Puede ajustar Date() o Date.now() para forzar que sea monótono (pero inexacto). Boceto, sin probar:

var offset = 0; var seen = 0; function time() { var t = Date.now(); if (t < seen) { offset += (seen - t); } seen = t; return t + offset; }

Si el reloj del sistema se retrasa en un momento dado, parecerá que no ha transcurrido ningún tiempo (y que el tiempo transcurrido que contenga ese intervalo será incorrecto), pero al menos no tendrá deltas negativas. Si no hay Date.now() esto devuelve el mismo valor que Date.now() .

Esta podría ser una solución adecuada si está escribiendo un ciclo de simulación de juegos, por ejemplo, cuando se llama a time() mucha frecuencia: el error máximo es el número de contratiempos multiplicado por el intervalo entre llamadas. Si su aplicación no hace eso de forma natural, podría llamarlo explícitamente en un setInterval , por ejemplo (suponiendo que no esté cubierto por el reloj del sistema), para mantener su precisión al costo de algún tiempo de CPU.

También es posible que el reloj se adelante , lo que no evita la monotonicidad, pero puede tener efectos igualmente indeseables (por ejemplo, un juego que pasa demasiado tiempo intentando ponerse al día con su simulación). Sin embargo, esto no se distingue especialmente de la máquina que ha estado dormida durante algún tiempo. Si se desea tal protección, solo significa cambiar la condición junto a la existente, con un umbral constante para el progreso aceptable:

if (t > seen + leapForwardMaximum) { offset += (seen - t) + leapForwardMaximum; }

Yo sugeriría que leapForwardMaximum debería configurarse en más de 1000 ms porque, por ejemplo, Chrome (si recuerdo correctamente) acelera los temporizadores en las pestañas de fondo para que se leapForwardMaximum no más de una vez por segundo.