Event Loop in JS
Reference video: https://www.youtube.com/watch?v=8aGhZQkoFbQ
What is an event loop?
An event loop is a continuous process that moves tasks from the callback queue to the call stack when the call stack is empty.
...and what is a callback queue and a call stack? To answer that let's understand what Javascript really is and how it works.
So what is javascript?
Javascript is a single-threaded, non-blocking, asynchronous, concurrent language.
Yeah I don't understand that either.
Broken down, the definition would mean this:
- Single threaded -> only has one call stack
- Non-blocking -> main thread does not wait for completion
- Asynchronous -> results are handled after the call returns
- Concurrent -> multiple tasks can be in progress at the same time
Now combining these pieces back together,
Javascript is a single threaded process that does not wait for completion of asynchronous tasks but instead continues execution. When an asynchronous task completes, the result is then scheduled to be handled by the main thread. Multiple such asynchronous tasks can be initiated without waiting for the earlier ones to finish.
I also know that there is some relationship between Node.js, v8 Engine and Javascript...
- v8 Engine is JIT Compiler, that parses, compiles and executes javascript code. It does not have event loops, or any of the APIs that we use BUT it does provide the call stack that we spoke about earlier.
- Node.js is a Runtime Environment and this is where the magic truly happens. The runtime environment adds a runtime layer that includes access to event loops, callback queues, system APIs, etc.
Javascript code that runs on browsers is run inside browser's own environment which provides WebAPIs instead of System APIs
Do we finally understand callback queues and call stacks?
Almost.
We have all the context we need to finally understand how event loop, callback queues and call stacks finally come together.
Call stack
A call stack is nothing but a stack that stores
- Which function is executing currently
- How execution should return once it finishes
Every language has a call stack which broadly functions this way.

The video explains it really well.
Callback queue
A callback queue is maintained by the javascript runtime which holds callback functions from completed asynchronous operations that are ready to be executed once the call stack is empty.
A callback function is a function we want to execute after the async operation is complete. It receives the result of that operation and continues execution from that point using that result however it wants. It gets pushed onto the callback queue waiting to be executed.
Let's illustrate the entire flow using this excellent tool philip created tool. Pasting code for reference.
$.on('button', 'click', function onClick() {
setTimeout(function timer() {
console.log('You clicked the button!');
}, 2000);
});
console.log("Hi!");
setTimeout(function timeout() {
console.log("Click the button!");
}, 5000);
console.log("Welcome to loupe.");
When you run the above tool you can see exactly how the code executes line by line: functions are pushed onto the stack when invoked and removed once the execution completes. When setTimeout() is called, it registers a timer and returns immediately. After the specified delay, the callback (in this case timeout()/timer()) is pushed onto the queue by runtime.
While all this is going on, the event loop is quietly running in the background monitoring the queue and the call stack for any new callbacks that need to be pushed onto the stack. Once the call stack is empty, the event loop picks up the callback function and pushes it onto the call stack.

And that is what an event loop does.