Entendiendo setImmediate()
Cuando deseas ejecutar algún fragmento de código de forma asíncrona, pero lo antes posible, una opción es utilizar la función setImmediate()
proporcionada por Node.js:
setImmediate(() => {
// do something
})
Cualquier función pasada como argumento de setImmediate()
es una devolución de llamada que se ejecuta en la siguiente iteración del bucle de eventos.
¿En qué se diferencia setImmediate()
de setTimeout(() => {}, 0)
(pasando un tiempo de espera de 0 ms), y de process.nextTick()
y Promise.then()
?
Una función pasada a process.nextTick()
se ejecutará en la iteración actual del bucle de eventos, después de que termine la operación actual. Esto significa que siempre se ejecutará antes que setTimeout
y setImmediate
.
Una devolución de llamada setTimeout()
con un retraso de 0 ms es muy similar a setImmediate()
. El orden de ejecución dependerá de varios factores, pero ambos se ejecutarán en la siguiente iteración del bucle de eventos.
Una devolución de llamada process.nextTick
se agrega a la cola process.nextTick. Una devolución de llamada Promise.then()
se agrega a la cola de microtareas de promesas. Una devolución de llamada setTimeout
, setImmediate
se agrega a la cola de macrotareas.
El bucle de eventos ejecuta las tareas en la cola process.nextTick primero, y luego ejecuta la cola de microtareas de promesas, y luego ejecuta la cola de macrotareas setTimeout
o setImmediate
.
Aquí hay un ejemplo para mostrar el orden entre setImmediate()
, process.nextTick()
y Promise.then()
:
const baz = () => console.log('baz');
const foo = () => console.log('foo');
const zoo = () => console.log('zoo');
const start = () => {
console.log('start');
setImmediate(baz);
new Promise((resolve, reject) => {
resolve('bar');
}).then(resolve => {
console.log(resolve);
process.nextTick(zoo);
});
process.nextTick(foo);
};
start();
// start foo bar zoo baz
Este código primero llamará a start()
, luego llamará a foo()
en la cola process.nextTick. Después de eso, manejará la cola de microtareas de promesas, que imprime bar y agrega zoo()
en la cola process.nextTick al mismo tiempo. Luego llamará a zoo()
que se acaba de agregar. Al final, se llama a baz()
en la cola de macrotareas.
El principio antes mencionado se cumple en los casos de CommonJS, pero tenga en cuenta que en los módulos ES, por ejemplo, los archivos mjs
, el orden de ejecución será diferente:
// start bar foo zoo baz
Esto se debe a que el módulo ES que se está cargando se envuelve como una operación asíncrona, y por lo tanto, todo el script ya está en la cola de microtareas de promesas. Entonces, cuando la promesa se resuelve inmediatamente, su devolución de llamada se agrega a la cola de microtareas. Node.js intentará borrar la cola hasta pasar a cualquier otra cola, y por lo tanto verá que imprime bar primero.