¿Cómo funciona Event Loop en JavaScript?
Si bien puede requerir una comprensión profunda de lenguajes como C ++ y C para escribir código de producción a gran escala, JavaScript a menudo se puede escribir con solo una comprensión básica de lo que se puede hacer con el lenguaje.
Concepts, like passing callbacks to functions or writing asynchronous code, are often not so difficult to implement, which makes most JavaScript developers care less about what goes on under the hood. They just don’t care about understanding the complexities that have deeply abstracted de ellos por el idioma.
As a JavaScript developer, it becomes increasingly important to understand what really happens under the hood and how most of these complexities abstracted from us really work. It helps us make more informed decisions, which can, in turn, boost our code performance drastically.
Este artículo se centra en uno de los conceptos o términos muy importantes pero que rara vez se comprenden en JavaScript. los ¡EVENTO BUCLE !.
Escribiendo unsynchronous code can not be avoided in JavaScript, but why does a code running asynchronously really mean? i.e. El bucle de eventos
Before we can understand how the event loop works, we first have to understand what JavaScript itself is and how it works!
¿Qué es JavaScript?
Before we proceed, I’d like us to take a step back to the very basics. What really is JavaScript? We could define JavaScript as;
JavaScript is an high level, interpreted, single threaded non-blocking, asynchronous, concurrent language.
Espera, ¿qué es esto? ¿Una definición libresca? 🤔
¡Vamos a analizarlo!
Las palabras clave aquí con respecto a este artículo son de un solo hilo, sin bloqueo, concuralquilar, y asynchonrado.
Hilo único
A thread of execution is the smallest sequence of programmed instruction that can be managed independently by a scheduler. A programming language is single-threaded means it can only perform one task or operation at a single time. This means it would execute an entire process from start to end without the thread being interrupted or stopped.
Unlike multi-threaded languages where multiple processes can be run on several threads concurrently without blocking each other.
¿Cómo puede JavaScript ser de un solo subproceso y sin bloqueo ¿al mismo tiempo?
Pero, ¿qué significa bloquear?
Sin bloqueo
No existe una definición única de bloqueo; simplemente significa cosas que se están ejecutando lentamente en el hilo. Entonces, no bloquear significa cosas que no son lentas en el hilo.
Pero espera, ¿dije que JavaScript se ejecuta en un solo hilo? Y también lo dije sin bloqueo, lo que significa que la tarea se ejecuta rápidamente en la pila de llamadas. ¿¿¿Pero cómo??? ¿Qué tal cuando ejecutamos temporizadores? Bucles?
Relax! We’d find out in a bit 😉.
Concuralquiler
Concurrency means that the code is being executed concurrently by more than one thread.
Okay, things are getting really extraño now, how can JavaScript be single-threaded and be concurrent at the same time? i.e., executing its code with more than one thread?
Asynchonrado
Asynchronous programming means that the code runs in an event loop. When there is a blocking operation, the event is started. The blocking code keeps running without blocking the main execution thread. When the blocking code finishes running, it queue’s the result of the blocking operations and pushes them back to the stack.
¿Pero JavaScript tiene un solo hilo? Entonces, ¿qué ejecuta este código de bloqueo mientras permite que se ejecuten otros códigos en el hilo?
Antes de continuar, repasemos lo anterior.
- JavaScript es de un solo subproceso
- JavaScript is non-blocking, i.e. slow processes don’t block its execution
- JavaScript es concurrent, i.e. it executes its code in more than one thread at the same time
- JavaScript es unsynchronous, i.e., it runs blocking code somewhere else.
But the above doesn’t exactly add up, how can a single-threaded language be non-blocking, concurrent, and asynchronous?
Let’s go a bit deeper, let’s go down to the JavaScript runtime engines, V8, perhaps it has some hidden threads we aren’t aware about.
Motor V8
The V8 engine is a high performance, Open-source web assembly runtime engine for JavaScript written in C++ by Google. Most browsers run JavaScript using the V8 engine, and even the popular node js runtime environment uses it too.
En inglés simple, el V8 es un programa C ++, que recibe código JavaScript, lo compila y lo ejecuta.
El V8 hace dos cosas importantes;
- Asignación de memoria de pila
- Contexto de ejecución de la pila de llamadas
Lamentablemente, nuestra sospecha estaba equivocada. El V8 tiene solo una pila de llamadas, piense en la pila de llamadas como el hilo.
Un hilo === una pila de llamadas === una ejecución a la vez.

Since V8 has just one call stack, how then does JavaScript run concurrently and asynchronously without blocking the main execution thread?
Let’s try to find out by writing a simple yet common asynchronous code and analyze it together.
JavaScript runs each code line by line, one after each other(single-threaded). As expected, the first line gets printed in the console here, but why is the last line printed before the timeout code? Why doesn’t the execution process wait for the timeout code(blocking) before going ahead to run the last line?
Algún otro hilo parece habernos ayudado a ejecutar ese tiempo de espera, ya que estamos bastante seguros de que un hilo solo puede ejecutar una sola tarea en cualquier momento.
Echemos un vistazo al Código fuente V8 por un momento.
¡¡¡¿¿Esperar lo??!!! ¿No hay funciones de temporizador en V8, no DOM? ¿No hay eventos? ¿Sin AJAX?…. Yeeeeessss !!!
Los eventos, DOM, temporizadores, etc. no forman parte de la implementación central de JavaScript, JavaScript se ajusta estrictamente a las especificaciones de Ecma Scripts y a menudo se hace referencia a varias versiones de él de acuerdo con sus Especificaciones de Ecma Scripts (ES X).
Flujo de trabajo de ejecución
Events, timers, Ajax requests are all provided on the client-side by the browsers and are often referred to as Web API. They are the ones that allow the single-threaded JavaScript to be non-blocking, concurrent, and asynchronous! But how?
Hay tres secciones principales para el flujo de trabajo de ejecución de cualquier programa JavaScript, la pila de llamadas, la API web y la cola de tareas.
La pila de llamadas
A stack is a data structure in which the last element added is always the first to be removed from the stack, you could think of it as a stack of a plate in which only the first plate which was the last added can be removed first. A Call Stack is simply nothing but a stack data structure where tasks or code is being executed accordingly.
Consideremos el siguiente ejemplo;

Cuando llamas a la función printSquare()
, se inserta en la pila de llamadas, printSquare()
la función llama al square() función. los square()
La función se inserta en la pila y también llama al multiply()
function. The multiply function is pushed onto the stack. Since the multiply function returns and is the last thing that was pushed to the stack, its get resolved first and is removed from the stack, followed by the square()
función y luego el printSquare()
función.
La API web
This is where code that isn’t handled by the V8 engine is executed to not “block” the main execution thread. When the Call Stack encounters a web API function, the process is immediately handed over to the Web API, where it is being executed and freeing the Call Stack to perform other operations during its execution.
Volvamos a nuestro setTimeout
ejemplo anterior;
When we run the code, the first console.log line gets pushed to the stack and we get our output almost immediately, on getting to the timeout, timers are handled by browser and aren’t a part of V8’s core implementation, it’s get pushed to the Web API instead, freeing the stack so it could perform other operations.
While the timeout is still running, the stack goes ahead to the next line of action and runs the last console.log, which explains why we get that outputted before the timer output. Once the timer is completed, something happens. The console.log in then timer magically appears in the call stack again!
¿Cómo?
El bucle de eventos
Antes de discutir el ciclo de eventos, veamos primero la función de la cola de tareas.
Back to our timeout example, once the Web API finishes executing the task, it doesn’t just push it back to the Call Stack automatically. It goes to the Cola de tareas.
Una cola es una estructura de datos que funciona según el principio Primero en entrar, primero en salir, de modo que a medida que las tareas se introducen en la cola, salen en el mismo orden. Las tareas que han sido ejecutadas por las API web, que se envían a la cola de tareas, luego regresan a la pila de llamadas para imprimir su resultado.
Pero espera. ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿?? ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿???

The event loop is a process that waits for the Call Stack to be clear before pushing callbacks from the Task Queue to the Call Stack. Once the Stack is clear, the event loop triggers and checks the Task Queue for available callbacks. If there are any, it pushes it to the Call Stack, waits for the Call Stack to be clear again, and repeats the same process.

The above diagram demonstrates the basic workflow between the Event Loop and the Task Queue.
Conclusión
While this is a very basic introduction, the concept of asynchronous programming in JavaScript gives enough insight to clearly understand what is going on under the hood and how JavaScript is able to run concurrently and asynchronously with just a single thread.
JavaScript está siempre bajo demanda, y si tiene curiosidad por aprender, le aconsejo que consulte este Curso Udemy.