How Event Loop Works in Javascript

Posted By : Satwinder Singh | 24-Oct-2018

We have always heard that javascript is a single-threaded asynchronous programming language. But what does it actually mean? And where does the event loop come into the picture? Let’s find out.

 

function delayBySeconds(sec){
     let start = now = Date.now();
     while(now – start < (sec*1000)){
         now = Date.now();
     }
}

 

When we see javascript as a single-threaded language it means that the main thread on which the javascript code is executed runs code on one line at a timely manner where there is no possibility of doing stuff in parallel. To understand this let’s have look on the function given below:-

The above function takes a number of seconds as an argument and then executes for those min number of seconds. If we call this function with ‘5’ as input, for the next five seconds the main javascript thread i.e. the runtime is blocked and cannot do anything else. If there was a button on the screen and you try clicking it, for the next five seconds it would not respond and that would be quite a bad user experience. Let us see another example where single-threaded nature of javascript can really put us at disadvantage.

Consider making a network request, a textbook example of some async event that takes time to come back. What if the code to handle the network request was written in a synchronous, blocking way. It would look something like this:-

 

makeNetworkRequest();

while(!networkRequestReturned()){
     //just keep looping
}

//runs after request returned

 

The above code would be a very bad way of doing things. This code blocks the line of execution at the condition to check whether the network request has returned and in the meanwhile the main thread, the runtime would remain blocked entertaining no other requests or user inputs. Anyways, no one does the code in this way as there is a better way of achieving this through callbacks. So, then how does javascript solve the problem of making network requests. One method is using a callback function. When we use callbacks we make a network request but along with it specify a callback function, a function that will be called when the network request comes back. It is to be noted that the javascript runtime does not have to keep waiting at a particular line of code checking for the network request as the callback function will be automatically invoked when the network request is completed.

So we would wonder how will this happen? If javascript was single-threaded and the runtime already moved ahead of the line of code making the network request then who was waiting for the network request to come back? Who called the callback function when the network request completed. That is indeed a good question to ask.

To understand this we must clear out some basic fundamentals in javascript and understand the memory organization in javascript. This is a rough rather famous representation of how javascript memory is organized. We have a heap region which works on relatively random allocations and is basically used for memory allocations. And we have a stack region which allocates memory in the form of a stack and is used to manage functions. For the purpose of the understanding event loop, we are more interested in learning about the stack. Have a look on the image give below to understand function call stack in a better way.

 

 

Function Call Stack :-The function stack is nothing but a stack which keeps track of the functions currently being executed in the runtime. Let us understand the stack generated by the function in the above image. The main() function is called first and so the stack gets its first item “main”. The levelOne() function is called from the main function and thus another item is pushed onto the stack, levelOne() calls levelTwo() and this is pushed on to the stack as well. In levelTwo() the function console.log() gets called which is also pushed onto the stack, then the message is printed onto the console. As soon as this happens the console.log() is popped off the stack, the levelTwo() function ends and it is popped off the stack as well. Same is the case with level One() and main() as well. So, basically we get the idea, a function when called is loaded onto the stack and once it gets over it is popped off the stack. That is how the function call stack works. Let us have a basic into about web APIs.

 

Web APIs:- Web APIs are set of functionalities that help us to perform additional tasks that are difficult to perform on the main thread. Think of them as the capabilities provided to us by the browser. As we had concluded that the runtime is single-threaded and it actually is but it can always export tasks to the web APIs which has the capability of responding to multiple threads. Let’s take an example of setTimeout() for an instance. When we call it the browser would delegate a thread to count that many numbers of milliseconds and then call the callback function after that or consider a network request to which the browser could delegate another thread and keep waiting for the response. In short, the javascript runtime is single threaded whereas the browser, on the other hand, has the capability to spawn multiple threads to perform tasks assigned to it.

 

The Event Loop:- Now we are well equipped to understand javascript event loop. To state it roughly, the event loop is that entity which pulls stuff out of the event queue and places it onto the function execution stack whenever the function stack becomes empty. We already know about function call stack and the web APIs but what is an event queue?

The event queue is a special queue that keeps the track of all the events that are appended to get executed in javascript. They are that piece of code that is waiting to run but hasn’t yet got scheduled to run. So how does all this stuff work together? Let understand with the help of setTimeout() function. Let us say we have this code setTimeout(func, 5000); somewhere in our code file. When this line is executed, it is loaded onto the function stack(refer to image1).

 

image 1

 

Once executed it calls a web API provided by the browser. This web API then fires a timer for 5000 milliseconds(refer to image2).

 

image 2

 

In the meanwhile, the setTimeout() function is executed as far as the runtime is considered and the code execution flow continues. After 5000 milliseconds have elapsed the web API takes the callback function and places it in the event queue(refer to image 3). Noted that the callback function is not yet run and is waiting for its turn on the js runtime.

 

image 3

 

When the function stack becomes empty i.e. all the elements are loaded off the stack, that is when the event loop comes into the picture. It takes the first function waiting on the event queue and places it onto the stack(refer to image 4), in this case, the callback function.

 

image 4

 

Then onwards that function executed calling other functions inside it if any. This cycle of calling web APIs, events getting added to the event queue and then getting loaded onto the function execution stack continues and that precisely is how javascript handles events. And that, in short, is the essence of the javascript event loop. That is how javascript gives us the illusion of being multi-threaded. This is how it performs time-consuming functions while still being available for user interactions.

 

About Author

Author Image
Satwinder Singh

Satwinder had been working as a free-lancer for past 1-year and recently joined Oodles Technologies as a UI-Developer. His skills are : Jquery , Html , Css , Bootstrap and Javascript.

Request for Proposal

Name is required

Comment is required

Sending message..