DEV Community

Shwetabh Shekhar
Shwetabh Shekhar

Posted on

Event Loop and Single Thread Mechanism in JavaScript.

"JavaScript is a single-threaded, non-blocking, asynchronous, concurrent language."

Any Javascript book/tutorial has this line etched in their introduction. On top of that this compact line is perplexing. How exactly is Javascript single-threaded? If so, how does it handle multiple API calls? Isn't Javascript synchronous? Then, how does it perform asynchronous execution? How is Javascript concurrent?

Here is my attempt to answer all these questions and explain how exactly the single thread mechanism works. Let's first try to understand the technical jargon thrown at us in the introductory line.

Single Thread

If a language is single-threaded it signifies, it has only one execution context or thread. What it essentially means is at most one of the blocking functions can execute at a time.

Non-Blocking

In a non-blocking language, the execution never stops or blocked.

Asynchronous and Synchronous Execution

When you execute something synchronously, you wait for it to finish before moving on to another task. Javascript is actually synchronous but it can be manipulated to behave in an asynchronous way.

Concurrent Execution

Concurrency basically signifies the execution of a multitude of tasks over a period of time which JS is very well capable of.

How does everything fit together?

Now that we have those technicalities out of our way let's try to understand how everything fits together. Consider the following code snippet:

console.log('before');
setTimeout(()=> {
    console.log('Inside SetTimeout');
},3000)
console.log('after');
Enter fullscreen mode Exit fullscreen mode

Mull it over and try to figure out its execution flow. Since Javascript is single-threaded, does it wait 3 seconds at setTimeout() and then move to console.log()? We all know that is not the case. Then how does it work? It all is taken care of by the Javascript engine model depicted below:

Javascript Event Loop
Image credits:

  1. Memory Heap: This is where the memory allocation happens.
  2. Call Stack: This is where your stack frames are as your code executes. It records where we are in the program. Each entry into the stack is called a stack frame.
  3. Web API: They are not provided by the engine but the Browser (like the DOM, AJAX, setTimeout)
  4. Callback queue: Once the Web APIs have executed they are moved to the callback queue.
  5. Event Loop: When there is no stack frame it moves the result to the stack.

Code Execution Flow

The above model is what makes Javascript tick. Any blocking task is passed on to the Web APIs for execution. Once it completes it is moved to callback queue in the order their execution was finished. Once the Call Stack is empty the event loop moves the output to call stack. This is how Javascript remains always non-blocking as execution is just moved to Web APIs.

Here is the line by line execution flow for the above example:

  1. First-line console.log() goes into the call stack and then executes.
  2. Execution moves to the second line. It is executed asynchronously. SetTimeout is passed to the web APIs and then once the task is completed it is moved to the Callback Queue.
  3. While the above process is happening the third line executes.
  4. The call stack is now empty. The event loop moves th e setTimeout output from the callback queue to the stack.

The above model is what makes Javascript very powerful. It provides it with excellent concurrency and the ability to handle asynchronous calls.

PS: This video by Philip Roberts is by far the best resource out there to understand this in more detail.

Top comments (0)