2011-08-28 9 views
34

En navegadores, si usa setTimeout desde una función llamada por setTimeout, se aplicará una demora mínima de 4ms. El wiki del desarrollador de Mozilla describes this behaviour, y menciona que tiene become standardized in HTML5.¿Node.js impone un retraso mínimo para setTimeout?

Node.js documentation for setTimeout no menciona un retraso mínimo. Sin embargo, la documentación para the process.nextTick function lo describe como una alternativa más eficiente al setTimeout(fn, 0). Esto sugiere la posibilidad de que sea más eficiente porque evita este retraso. De lo contrario, setTimeout(fn, 0) probablemente podría optimizarse para que se comporte igual.

¿Node.js impone un retraso mínimo para setTimeout, como lo hacen los navegadores web?

Respuesta

17

No tiene un retraso mínimo y esto es en realidad un problema de compatibilidad entre los navegadores y el nodo. Los temporizadores no están especificados en JavaScript (es una especificación DOM que no tiene uso en Node y ni siquiera son seguidos por los navegadores) y el nodo los implementa simplemente debido a lo fundamentales que han sido en la historia de JavaScript y lo irremplazables que son.

Node usa libuv, que es una capa de abstracción multiplataforma para cosas de sistema de nivel inferior como sistema de archivos, elementos de red, etc. Una de esas cosas son los temporizadores, que Node proporciona un envoltorio mínimo. En el nivel de libuv, los temporizadores utilizados son los temporizadores de alta precisión específicos del sistema. En Windows, por ejemplo, esto se implementa usando QueryPerformanceFrequency y FileTimeToSystemTime que proporciona una resolución medida en nanosegundos.

En el nodo, si especifica setTimeout(callback, 1), se ejecutará un milisegundo más tarde (suponiendo que el sistema no lo demora debido a que está sobrecargado). En navegadores, el tiempo mínimo será de 4 milisegundos según lo especificado por la especificación HTML5: https://developer.mozilla.org/en/DOM/window.setTimeout. Este no es un tiempo garantizado, solo un mínimo.Se puede esperar que la mayoría de los navegadores tengan una resolución de ~ 15ms que afecta las animaciones DOM.

Una pieza válida de información es que los tiempos de espera establecidos en el mismo milisegundo, durante el mismo marco, se ejecutarán en el orden en que se pusieron en cola. Si tuviera que hacer:

setTimeout(callback1, 1); 
    setTimeout(callback2, 1); 
    setTimeout(callback3, 1); 
    setTimeout(callback4, 1); 

Todo en un bloque, Node debe llamarlos en ese orden. Esto solo se aplica si tienen exactamente el mismo tiempo de resolución.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724280(v=vs.85).aspx

15

De esta prueba, no parece que tenga un retraso mínimo.

Si lo hace un setTimeout() que tiene una duración 10ms, y durante mucho tiempo el valor de retorno a la consola, esto es lo que hay:

var timer = setTimeout(function(){ console.log(timer);}, 10); 

{ _idleTimeout: 10, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:41 GMT } 

Del mismo modo, con una duración 1ms, se obtiene:

var timer = setTimeout(function(){ console.log(timer);}, 1); 

{ _idleTimeout: 1, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:59 GMT } 

Pero si realiza una duración de 0, no obtendrá una propiedad _idleTimeout:, lo que parecería sugerir que la devolución de llamada se invoca de inmediato, aunque de forma asíncrona.

var timer = setTimeout(function(){ console.log(timer);}, 0); 

{ repeat: 0, callback: [Function] } 

Por otra parte, si lo hago simple comparación fecha de inicio/final, por lo general consigo 0 como el resultado de restar el comienzo del final.

var start = Date.now(); 
var timer = setTimeout(function(){ console.log(timer, Date.now() - start);}, 0); 

{ repeat: 0, callback: [Function] } 0 

Estas pruebas se realizaron utilizando Node.js 0.5.2.

1

Cabe señalar que la implementación del temporizador variará según el sistema operativo. Por ejemplo, recuerdo un problema de JTimer "muy viejo" en el que la resolución del temporizador era 16 ms en Windows y ~ 1 ms en otras plataformas. Es casi seguro que vale la pena probarlo en su servidor particular.

Cuestiones relacionadas