Recientemente me preguntaron en una entrevista si conocía el Event Loop y desgraciadamente tuve que responder no. Manejo y entiendo los Callbacks, las promesas y las funciones asíncronas, pero jamás había oido hablar de esto concretamente. Vamos a explorar el comportamiento del código en JavaScript para entenderlo mejor.

console.log("Paso 1")

setTimeout(() => console.log("después"), 1000)

console.log("Paso 2")

// El resultado por consola sería:
// Paso 1
// Paso 2
// después

Como podemos observa, la función setTimeout no rompe el flujo de ejecución del código, este tipo de funciones se llaman webapi y son servicios que nos ofrece el navegador o runtime de JavaScript si estamos en node.js por ejemplo. Aquí es donde empezamos a hablar de threads o hilos. Cada hilo es un linea de ejecución secuencial y esta función recibe un callback para ejecutar cuando pase 1 segundo. Esto empezará a medirse en un nuevo hilo para seguir con la ejecución del código.

Con esta parte clara podemos pasar a definir que es el Event Loop

Cuando nuestro hilo en webapi está preparado para ejecutar el callback que le hemos definido, lo pasamos a una cola de tareas y cuando el hilo de ejecución principal se quede vacío es cuando ejecutaremos las tareas que tengamos en cola. Es por esto que aun que a setTimeout le hubiésemos puesto 0ms. para ser ejecutado, nuestro callback entraría al hilo principal cuando este se haya quedado libre.

Lo mismo pasaría con las llamadas remotas que hagamos, por ejemplo peticiones o envíos de formulario.

Entonces podemos definir de la forma más básica posible que Event Loop es un bucle que pondrá en ejecución las tareas en cola que nos pasen los webapis.

El renderizado de nuestra página es parte del Event Loop

A parte de la cola de tareas que iremos apilando con los callbacks que enviemos a nuestras webapis. Tenemos un cola de renderizado que también depende su ejecución de que nuestro thread principal esté libre. Esto nos congelará nuestra página por completo y no es una experiencia normalmente deseada.

Tendrá prioridad sobre las tareas en cola por lo que lo ideal es trabajar con pequeñas funcionen que no bloquen nuestra Call Stack o hilo principal.

console.log("Paso 1")

const slowCall = (num) => {
    const limit = 50000
    for (let x = 0; x < limit; x++) {
        for (let y = 0; y < limit; y++) {
            num **= 2
        }
    }
    return num
}

setTimeout(() => {
    console.time()
    console.log(slowCall(2))
    console.timeEnd()
}, 0)

console.log("Paso 2")

// El resultado por consola sería:
// Paso 1
// Paso 2
// Infinity
// default: 3174.600830078125 ms

En este ejemplo dejamos inutilizada la web durante unos 3 segundos.

¿Cuantas colas tiene Event Loop?

Vamos a complicar un poco más el tema, hemos visto que la cola de renderizado tiene prioridad sobre el resto, existen multiples colas en Event Loop, algunas de ellas son:

Render: Como la primera de todas
DOM Tasks: Para las callbacks que modifican o actúan directamente sobre el DOM, como cambiar un texto.
UI Tasks: Almacenará las de interacción del usuario con eventos como click o scroll.
NET Tasks: Con las de peticiones que hagamos fuera de nuestra red.
History Tasks: Con las que interfiramos en la navegación como history.back()
Timer Tasks: La cola con menos prioridad de todas almacenará las callbacks de webapis como setTimeout por ejemplo.

Si te interesa puedes leer más sobre las tareas y colas en las especificaciones de Event Loop.

Si quieres consultar la fuente de donde he encontrado la información que he tratado de resumir este post puede ver el siguiente video de YouTube donde los explican de una forma genial.

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Instagram