temporizador node nexttick loop avoid node.js

node.js - nexttick - node js timer loop



nextTick vs setImmediate, explicación visual (5)

A continuación te brindamos una mayor claridad.

setImmediate

  1. Se ejecuta una secuencia de comandos una vez que se completa la fase de encuesta actual.
  2. Es una función de módulo de temporizador y las funciones del temporizador son globales, puede llamarlas sin necesidad.
  3. Se puede borrar por clearImmediate ().
  4. Establezca la ejecución "inmediata" de la devolución de llamada después de las devoluciones de llamadas de los eventos de E / S antes de setTimeout () y setInterval ().

nextTick

  1. Es una función de objeto global de proceso de NodeJS.
  2. Todas las devoluciones de llamadas pasadas a process.nextTick () se resolverán antes de que continúe el bucle de evento.
  3. Permitir a los usuarios manejar los errores.
  4. Ayuda a probar la solicitud nuevamente antes de que el ciclo de eventos continúe.

Fragmento de código simple.

console.log("I''m First"); setImmediate(function () { console.log(''Im setImmediate''); }); console.log("I''m Second"); process.nextTick(function () { console.log(''Im nextTick''); }); console.log("I''m Last"); /* Output $ node server.js I''m First I''m Second I''m Last Im nextTick Im setImmediate */

Estoy muy confundido acerca de las diferencias entre nextTick y setImmediate. He leído toda la documentación sobre ellos en Internet, pero todavía no entiendo cómo funcionan.

Ejemplos:

function log(n) { console.log(n); }

setImmediate

setImmediate(function() { setImmediate(function() { log(1); setImmediate(function() { log(2); }); setImmediate(function() { log(3); }); }); setImmediate(function() { log(4); setImmediate(function() { log(5); }); setImmediate(function() { log(6); }); }); }); //1 2 3 4 5 6

nextTick

process.nextTick(function() { process.nextTick(function() { log(1); process.nextTick(function() { log(2); }); process.nextTick(function() { log(3); }); }); process.nextTick(function() { log(4); process.nextTick(function() { log(5); }); process.nextTick(function() { log(6); }); }); }); //1 4 2 3 5 6

¿Por qué estos resultados? Por favor explique con una explicación visual o muy fácil de seguir. Incluso los desarrolladores de núcleos de nodos no están de acuerdo con la forma en que NextTick y setImmediate deberían ser entendidos por las personas.

Fuentes:


Considere los siguientes dos ejemplos:

setImmediate

setImmediate(function A() { setImmediate(function B() { log(1); setImmediate(function D() { log(2); }); setImmediate(function E() { log(3); }); }); setImmediate(function C() { log(4); setImmediate(function F() { log(5); }); setImmediate(function G() { log(6); }); }); }); setTimeout(function timeout() { console.log(''TIMEOUT FIRED''); }, 0) // ''TIMEOUT FIRED'' 1 4 2 3 5 6 // OR // 1 ''TIMEOUT FIRED'' 4 2 3 5 6

nextTick

process.nextTick(function A() { process.nextTick(function B() { log(1); process.nextTick(function D() { log(2); }); process.nextTick(function E() { log(3); }); }); process.nextTick(function C() { log(4); process.nextTick(function F() { log(5); }); process.nextTick(function G() { log(6); }); }); }); setTimeout(function timeout() { console.log(''TIMEOUT FIRED''); }, 0) // 1 4 2 3 5 6 ''TIMEOUT FIRED''

set Las llamadas intermedias se activan desde el bucle de evento, una vez por iteración en el orden en que se pusieron en cola. Por lo tanto, en la primera iteración del ciclo de eventos, la devolución de llamada A se activa. Luego, en la segunda iteración del bucle de evento, se activa la devolución de llamada B, luego en la tercera iteración del evento se activa la devolución de llamada en bucle C, etc. Esto evita que el bucle de evento se bloquee y permite otras devoluciones de E / S o temporizadores llamado en el tiempo medio (como es el caso del tiempo de espera 0ms, que se dispara en la iteración de 1er o 2º bucle).

Las devoluciones de llamada nextTick, sin embargo, siempre se activan inmediatamente después de que el código actual se haya ejecutado y ANTES de volver al ciclo de evento. En el siguiente ejemplo de Tick, terminamos ejecutando todas las devoluciones de llamada nextTick antes de volver al bucle de evento. Dado que se llamará a la devolución de llamada de setTimeout desde el bucle de evento, el texto ''TIEMPO DISPARADO'' no se emitirá hasta que hayamos terminado con cada devolución de llamada siguiente.


Creo que todas las respuestas anteriores son obsoletas, porque tengo respuestas diferentes constantemente con la versión actual de nodejs y es fácil razonar sobre

var log=console.log log(process.version) var makeAsyncCall if(false) makeAsyncCall=setImmediate else makeAsyncCall=process.nextTick; makeAsyncCall(function A () { makeAsyncCall(function B() { log(1); makeAsyncCall(function C() { log(2); }); makeAsyncCall(function D() { log(3); }); }); makeAsyncCall(function E() { log(4); makeAsyncCall(function F() { log(5); }); makeAsyncCall(function G() { log(6); }); }); }); //1 //4 //2 //3 //5 //6 //in both case

Después de leer https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md#processnexttick-vs-setimmediate, deje el uso comience desde setImmediate , deberíamos hacer un seguimiento de la check queue porque es donde setImmediate devolución de llamada setImmediate .

Primera iteración

A es presionar para check queue

cola de verificación: [A]

Segunda iteración

A es sacar de la queue para ejecutar

Durante su ejecución, puso B y E en queue y luego, A completa y comienza la próxima iteración

cola de verificación: [B, E]

Tercera iteración

saque B y presione C D

cola de verificación: [E, C, D]

Cuarta iteración

saca E y presiona F G

cola de verificación: [C, D, F, G]

Finalmente

ejecutar las devoluciones de llamada en la cola de forma secuencial

Para el caso nextTick , la cola funciona exactamente de la misma manera, es por eso que produce el mismo resultado

Lo diferente es eso:

el nextTickQueue se procesará después de que se complete la operación actual, independientemente de la fase actual del bucle de evento

Para que quede claro, el bucle de eventos mantiene múltiples colas y la check queue es solo una de ellas, el nodo decidirá qué cola usar según algunas reglas

con process.nextTick sin embargo, es una especie de puentear toda la regla y ejecutar la devolución de llamada en nextTick inmediatamente


No puedo reproducir tus resultados para setImmediate . Debería ser lo mismo que nextTick (y está en mis pruebas) ya que en esta situación hacen casi lo mismo. La única explicación razonable para eso es que setImmediate es de alguna manera sincrónico, pero no lo es.

Y de acuerdo con la documentación de NodeJS, la única diferencia real es que múltiples nextTick pueden dispararse en una iteración de bucle (dependiendo de maxTickDepth ), mientras que setImmediate dispara una vez por iteración.


Según los nombres de archivo Node.js de estas dos funciones se cambian exactamente

setImmediate () ( MEJOR RECOMENDADO )

Primero es el fuego en la fila de eventos

process.nextTick () ( USE PARA CASOS ESPECIALES Vea ejemplo más adelante )

Es fuego inmediatamente, es un poco escribir una declaración más al final en el archivo actual

Si tenemos este código

setTimeout(function(){ console.log(''Hello world 5''); // It''s waiting like a normal person at a queue }, 0); setImmediate(function(){ console.log(''Hello world 4''); // It''s like get to last and be take care of first // but always after of .nextTick and before of setInterval(, 0) }); process.nextTick(function(){ console.log(''Hello world 3''); // It''s like be at the bottom at this file }); console.log(''Hello world 1''); console.log(''Hello world 2'');

Una explicación visual podría ser (como lo está preguntando):

Casos de uso process.nextTick () cuando tiene que emitir y evento antes para manejarlo:

const EventEmitter = require(''events''); const util = require(''util''); function MyEmitter() { EventEmitter.call(this); // use nextTick to emit the event once a handler is assigned process.nextTick(function () { this.emit(''event''); }.bind(this)); } util.inherits(MyEmitter, EventEmitter); const myEmitter = new MyEmitter(); myEmitter.on(''event'', function() { console.log(''an event occurred!''); });

Miren esta manera increíble de dar una explicación de ciclo de eventos en tiempo de ejecución de Philip Roberts y su evento de tiempo de ejecución en línea. Prueba en vivo de cómo funciona el bucle de eventos

Fuente: https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md#processnexttick-vs-setimmediate