I have been working with Javascript for more than a decade and for the first few years I did not know what event loop was. It was not until I started working heavily with NodeJS when I realised there is something called event loop and what it does. Javascript queues up the code (functions) it needs to execute in an event loop. Given it’s a queue, the order of how the code gets executed is determined by the order in which they appear in the event loop. An example of an event would be when a Javascript promise is resolved. In this post we will look at what the event loop is and how can we resolve it. So What is Javascript event loop? Built on the foundations of stack and queues, it is a runtime model of how Javascript executes code. Before going into too much details, let us know a bit about the background.

Background

I have been working with Javascript for a long time and I have to admit, it was not until 2011 or 2012 when I started working with an early version NodeJS, when I had the curiosity to know about it. My pursuit of knowing more about the advantages of NodeJS lead me to the discovery of the event loop.

To think of it, it is amazing of how long you can keeping going and call yourself a good Javascript engineer without knowing about the Event Loop and rightfully so. In fact heaps of Javascript engineers I know these days who are good at coding ReactJS, have no idea what the event loop is. It goes to show just how approachable Javascript is as a technology to build software with. It is incredible how it lets you be an expert without needing you to take a deep dive into what the technology is.

What is Javascript event loop?

You can think of event loop as a process of how the Javascript engine goes about executing Javascript code (functions, events etc) at runtime. Before you get into the details of the event loop, let’s have a quick recap on Stack and Queue data structure.

Queue and Stack

A queue as the name suggests is a lot like a queue in the real world. If you think about it, a queue in the real world e.g. you join a queue at a store to get a new phone, here the people in front of you will always be served before you. This means first come first serve or First In queue First Out (FIFO). The queue data structure follows the FIFO principle of storing data. You can enqueue (add) element to the back of the queue and dequeue (remove) element from the front of the queue.

Stack is probably my favourite data structure in Computer Science. A stack data structure uses the Last In First Out (LIFO) principle for storing data. You can push an element on top of the stack and pop an element from the end of the stack.

It will make sense a bit later on why these concepts are discussed here.

Call Stack

A call stack is a stack so if your code executes function a() it will be push (added) at the end of the call stack. Now if function a() calls function b() then b() will be push (ed) to the top of the stack, now if calls function c(), then c() will be pushed on top of the call stack. Given the call stack is a stack it uses the LIFO principle hence when you call a(), it will be added to the stack, when a() calls b(), b will be added on top of the stack, followed by c(). These functions will be resolved in the order in which they are removed from the stack, hence the order in which they would be resolved would be c -> b -> a.

Message Queue or Event Queue

An event queue is responsible for sending new functions to to the stack. It does so using a queue data structure so it track the order of execution for all the operations.

How does it all fit together?

Javascript executes functions in the order in which they are added to the queue, the first ones added to the queue are the first ones to be resolved. Understanding the Javascript event loop in more detail is all the more critical to modern web applications. The goal of modern web applications is to have a good user experience e.g. UX. Keeping the app responsive and smooth scrolling is considered good UX. Say if a user is scrolling down a web page to get some information about a city, at 20% from the top the page shows weather information followed by static text which is the history of the city. Now, while scrolling down the last thing you want is for the user to be stuck on the web page while it fetches weather info. You can think of it as there are 2 events, one is page scroll event and the other is fetch weather event. Your goal is to maintain good UX and let the user scroll, hence the load weather event is put at the back of the event queue until the information is retrieved while the user scroll is maintained.

To elaborate this example anymore would be to take a deep-dive into Javascript promises and that is a whole new thing way way beyond the scope of this post. So let’s have a look at some code samples to stalk about event loop. That is a lot of theory but you may wonder, how does it all fit together? That is best explained with code samples

function start() {
    console.log("Call start function");
}

function useTimeout() {
    console.log("Executing useTimeout function");
}

function afterTimeout() {
    console.log("Calling afterTimout");
}
start();
// let's put this in the back of the queue
setTimeout(useTimeout, 0); 
afterTimeout();

Executing the code above will result in the following output

Call start function
Calling afterTimout
Executing useTimeout function

In the code above

  1. The start function is executed almost immediately
  2. The useTimeout function is called within the setTimeout function
  3. Then the useTimeout function is called like the start function

The reason why afterTimeout function is executed before the useTimeout function is because, calling the setTimeout function even with a 0 second delay puts it at the back of the event queue.

The Call Stack

In the next piece of code you will see how the call stack comes to relevance in the context of the event loop.

function currentAddress() {
    console.log("return current address");
    return { address: 'P. Shreman, 42 Wallaby Ln, Sydney, 2000' };
}
function educationDetails() {
    console.log("return education details")
    return { university: 'University of New South Wales', courseAvg: 'HD'};
}
function personalDetails() {
    console.log('************** personalDetails call stack **************');
    const employee = {};
    employee.education = educationDetails();
    employee.address = currentAddress();
    console.log(`returning employee details,`);
    console.log(employee);
    return employee;
}

function employeeId() {
    console.log('employeeId()');
    return 'SOBHC33';
}
function companyName() {
    console.log('companyName()');
    return "My Day To-Do";
}
setTimeout(personalDetails, 0);
employeeId();
companyName();

Running the above code gives the following output,

employeeId()
companyName()
************** personal details call stack **************
return education details
return current address
{ education:
   { university: 'University of New South Wales', courseAvg: 'HD' },
  address: { address: 'P. Shreman, 42 Wallaby Ln, Sydney, 2000' } }

Notice how employeeId and companyName are printed first? That is because you see, personalDetails functions was called via setTimeout method which means the event loop puts it behind employeeId() and companyName() which are called immediately after.

Now, the educationDetails() and currentAddress() are also executed after employeeId and companyName, why? because they are within the personal details call stack. These functions are executed from within the personalDetails methods hence when the event loop puts the personal details at the back of the queue it does so for the functions executed from within.

From the context of the queue and stack data structure, as program execution starts this is how it plays out

  • personalDetails – employeeId – companyName : are queued
  • setTimeout dequeue personalDetails and enqueue it at the back hence, employeeId – companyName – personalDetails
  • dequeue employeeId to execute it, and the queue has companyName – personalDetails
  • dequeue companyName to execute it, and the queue has – personalDetails
  • dequeue personalDetails to execute it
    • push personalDetails onto of the stack
    • push educationDetails on top of the stack
    • pop educationDetails to execute it
    • push address on top of the stack
    • pop address to execute it
    • pop personalDetails to finish execution

Now you see how it all works and also understand why discussing basic concepts of stack and queue data structure was so important at the beginning.


Conclusion

What is Javascript event loop? As you read from this post essentially it is just a runtime model for executing Javascript code. Now you know what event loop is, you can think of the event loop as a mechanism through which Javascript is able to interact with external sources, manipulate data on a web page while staying responsive (non-blocking) for good UX.

Get updates?

If you find any of my posts useful and want to support me, you can buy me a coffee :)

https://www.buymeacoffee.com/bhumansoni

Or you can  buying or even try one of my apps on the App Store. 

https://mydaytodo.com/apps/

In addition the above, have a look at a few of the other posts,
How to create radio buttons using vanilla Javascript
https://mydaytodo.com/vanilla-javascript-create-radio-buttons/

How to build a Javascript frontend for Java Spring Boot backend 
https://mydaytodo.com/java-spring-boot-vanilla-javascript-solution/

Or have a look at some useful Javascript tutorials below
https://mydaytodo.com/category/javascript/
Categories: Javascript

0 Comments

Leave a Reply

Avatar placeholder