JavaScript Single-Thread Event Loop Work Flow Explained

JavaScript Single-Thread Event Loop Work Flow Explained

In this blog, we'll learn about how JavaScript works under the hood, how it can be used to effectively handle potential blocking operations such as fetching resources from a server.

We have always heard people mentioning that JavaScript is Single Threaded.

What do you mean by JS is single threaded?

In simple terms, JS is running at most one line of code at a time. It can switch back and forth between different lines of code very quickly. So we don't think that only one thing is happening at a time.

Single Thread Event Loop Work Flow

Java Script follows Single-Threaded with Event Loop Model. As JS follows this architecture, it can handle more and more concurrent client requests very easily.

Here are Single-threaded event loop model processing steps:

  1. Clients send the request to the webserver.
  2. JS web server internally maintains a limited thread pool to provide services to the client requests.
  3. JS web server receives those requests and places them into a stack, known as “Call Stack”. Let's write a simple code and track what's happening on the call stack. stack.gif As you can see, the functions are added to the stack, executed, and later deleted.
  4. Node JS web server internally has a component, known as “Event Loop”. (it got this name as it uses an indefinite loop to constantly checks if the call stack is empty or not).
  5. If the call stack is empty, then wait for incoming requests for an indefinite time.
  6. If it has a request, then it picks up the client's request from the call stack and starts processing it.
  7. If that request does not require any blocking IO operations, then process everything, prepare a response and send it back to the client.
  8. If it requires some blocking IO operations like interacting with database, file system, external services then it will follow a different approach, which is:

Checks Threads availability from Internal Thread Pool

Picks up one Thread and assign this Client Request to that thread.

That Thread is responsible for taking that request, process it, perform Blocking IO operations, prepare a response, and send it back to the Event Loop

Event Loop, in turn, sends that Response to the respective Client

Asynchronous behavior

However, JS can also be non-blocking and behave as if it were multi-threaded. It means that it doesn't wait for the response of a request, and can continue the code execution. It is possible thanks to the JS engines which use real multi-threading languages(like C++ (Chrome) or Rust (Firefox)), which provide us with the Web API.

How these Web APIs work:

  • Web APIs can handle certain tasks in the background (like making requests or setTimeout).

    The setTimeout() method executes a block of code after the specified time. The method executes the code only once. The commonly used syntax of setTimeout() is:

    setTimeout( function, millisecond)
    
  • JS call stack recognizes these functions and passes them off to web API.
  • Once Web API finishes those tasks, they return and are pushed onto the stack as a callback function

    In JavaScript, you can also pass a function as an argument to a function. This function that is passed as an argument inside of another function is called a callback function.

So Let's take an example to understand this:

console.log('I print First!');
setTimeout(() => {
      console.log('I print after 3 seconds');
}, 3000);
console.log('I print second!');

The first function is pushed to the call stack and I print First is immediately printed in the console. Then, we call the setTimeout function provided by the browser's Web API. It goes to the call stack and its asynchronous callback function goes to the WebApi's queue, where it waits for the call, set to happen after 3 seconds. In the meantime, the program continues and the next function is executed and I print second is printed in the console. So, when our setTimeout timer finishes the countdown, our callback function goes to the queue, waits until the call stack becomes available, and gets executed and prints I print after 3 seconds.

Conclusion:

If we consider how JS engines work under the hood, we can classify JS as an asynchronous and single-threaded language. And in this blog, we learned how & why JS is called that. Winding up now. Hope you liked it. Please share your valuable suggestions in the comments. Thanks for your valuable time. Stay home and healthy.