Búsqueda de sitios web

javascript - ¿Cómo funciona setTimeout en Node.JS?


Supongo que una vez que se ejecuta está en la cola, pero en la cola, ¿hay alguna garantía de que se invocará exactamente después de X milisegundos? ¿O otras tareas pesadas más arriba en la cola lo retrasarán?

Respuesta #1

La semántica de setTimeout es aproximadamente la misma que en un navegador web: el argumento timeout es un número mínimo de ms para esperar antes de ejecutar, no una garantía. Además, pasar 0, un valor que no sea número o un número negativo hará que espere un número mínimo de ms. En Node, esto es 1 ms, pero en los navegadores puede ser hasta 50 ms.

La razón de esto es que no hay preempción de JavaScript por JavaScript. Considera este ejemplo:

setTimeout(function () {
  console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')

El flujo aquí es:

  1. programa el tiempo de espera para 100 ms.
  2. espera ocupada durante 5000 ms.
  3. volver al bucle de eventos. comprobar los temporizadores pendientes y ejecutarlos.

Si este no fuera el caso, entonces podrías tener un bit de JavaScript que "interrumpa" a otro. Tendríamos que configurar mutexes y semáforos y cosas por el estilo, para evitar que un código como este sea extremadamente difícil de entender:

var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?

La ejecución de JavaScript de Node en un solo hilo hace que sea mucho más sencillo de trabajar que la mayoría de otros estilos de concurrencia. Por supuesto, la desventaja es que es posible que una parte del programa que se comporte mal bloquee todo con un bucle infinito.

¿Es este un demonio mejor para luchar que la complejidad de la prevención? Eso depende.

Respuesta #2

La idea de no bloqueo es que las iteraciones del bucle sean rápidas. Entonces, iterar en cada tick debería tomar un tiempo lo suficientemente corto como para que el setTimeout sea preciso dentro de una precisión razonable (con un desfase de quizás menos de 100 ms o algo así).

En teoría, sin embargo, tienes razón. Si escribo una aplicación y bloqueo el tick, entonces los setTimeout se retrasarán. Así que para responder a tu pregunta, ¿quién puede asegurar que los setTimeout se ejecuten a tiempo? Tú, escribiendo código no bloqueante, puedes controlar el grado de precisión hasta casi cualquier grado razonable de exactitud.

Mientras JavaScript sea "single-threaded" en términos de ejecución de código (excluyendo web-workers y similares), eso siempre ocurrirá. La naturaleza de un solo hilo es una gran simplificación en la mayoría de los casos, pero requiere el uso del paradigma no bloqueante para tener éxito.

Prueba este código ya sea en tu navegador o en node, y verás que no hay garantía de precisión, al contrario, el setTimeout será muy tardío:

var start = Date.now();

// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);

// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}

A menos que el intérprete optimice el bucle (lo cual no hace en Chrome), obtendrás algo en los miles. Elimina el bucle y verás que es 500 clavados...

Respuesta #3

setTimeout es un tipo de Hilo, mantiene una operación durante un tiempo dado y la ejecuta.

setTimeout(function,time_in_mills);

Aquí el primer argumento debería ser de tipo función; como ejemplo, si quieres imprimir tu nombre después de 3 segundos, tu código debería ser algo como lo siguiente.

setTimeout(function(){console.log('your name')},3000);

El punto clave a recordar es que, cualquiera que sea la acción que quieras realizar usando el método setTimeout, hazlo dentro de una función. Si quieres llamar a algún otro método pasando algunos parámetros, tu código debería verse como a continuación:

setTimeout(function(){yourOtherMethod(parameter);},3000);

Artículos relacionados