How Javascript Call Stack and Event Loop Works?

Michael Tong
Webtips
Published in
5 min readSep 27, 2020
How Javascript Call Stack and Event Loop Works?
Photo by Debby Hudson on Unsplash

Have you ever logged into a website like Facebook and wondered why the page is loaded before all the recent posts?

Have you ever wondered why when you are trying to view things you want to buy on Amazon, you see other components before the items you are interested to buy?

To understand this, let’s understand how operations are handled from a synchronous and an asynchronous point of view.

Javascript is synchronous by nature. It means it runs a series of instructions one at a time. If the first instruction has not finished executing, the next line of instruction would not be executed until the first instruction is finished.

Let’s take the following code as an example:

If you run the following javascript code here’s how the call stack would look like:

It adds each one of those instructions and run each one of them one at a time.

How about functions? When we call functions that have their set of statements how does it affect the call stack?

Let’s take a look at the following example:

Right here, we call multTwo, which calls mult of a and b and multiply it by 2. Notice a pattern here? It calls one after the other but the latest call on the stack will always be executed first.

Here’s how the call stack would look like:

multTwo gets called, which triggers the mult function call. 2 times 3 evaluates to 6, popping the top of the stack. Since mult(2*3) turns into 6, 2 * 6 turns into 12, popping another element on the stack. At last, multTwo(2,3) then gets evaluated.

Now one important question comes up:

If everything is running line by line, how come we still hear about concepts such as promises, asynchronous calls, etc?

That’s because there is a way to perform asynchronous operations with javascript.

Imagine going on your Facebook page and you are scrolling up and down. In a few seconds, you will see new posts coming up as there are more recent posts available.

If browsers are running on javascript and javascript is synchronous by nature, does that mean the browser either cannot be scrolled up and down when the browser is trying to fetch recent posts, etc?

Enter the event loop.

In javascript, when an asynchronous operation is made, the operation gets put into the event loop instead. Once all the operations are popped from the call stack, then the operations in the event loop get popped(some might be earlier, some might be later depending if they are set on a timeout or if they have returned from a call to get some API data).

Here is an example of some javascript asynchronous operations & synchronous operations:

Let’s say we don’t know how the event cycle in javascript works. We probably expect all of the code to run in order. However, if you run this code you will see the following output in this order:

  • c: 3
  • hi

Wait, what? Didn’t we call doSomething before we print out the value of c? To understand exactly why this is happening, we have to understand how javascript handles asynchronous operations.

Let’s take at the following diagram to see what actually to the javascript call stack and event loop on the example above:

After the first three lines of statements, each line gets ran once, one at a time, with each call being put into the call stack and popped immediately. After these statements, the call stack is empty and the heap contains the value of a, b, and c.

Let’s see what happens when the setTimeout statement and the console log statement is called:

When setTimeout is called, javascript quickly recognizes it as a web API called and pushes to the stack there. One key point to remember is any web API calls won’t be called until the call stack is empty. Because of that, console.log actually gets pushed into the call stack and gets popped first, triggering the console.log call.

Once the setTimeout timer expires, the callback of setTimeout is getting pushed into the call stack. Because doSomething calls console.log, now console.log gets pushed into the call stack.Console.log then gets popped off the stack and gets called and then doSomething gets popped off the stack.

Wow, there is a lot going on right?

To understand how javascript really operates, remember the few following concepts:

  • javascript is synchronous by nature. It runs line by line, push each item into a call stack, and popping them off immediately to run each call.
  • If it calls a function, it pushes the function call to the call stack and then the inner function calls into the call stack. The inner function call gets popped off the stack and triggered first before the main function call.
  • Asynchronous calls are put into the event loop instead of the call stack. Every operation in the call stack must be run before event loop operations are triggered, regardless of when these asynchronous calls received feedback (can be a success or fail response).

Feel free to comment or ask any questions if there are any.

Can you think of how many synchronous vs asynchronous calls are currently running in this article as you read through it?

Happy coding. Cheers.

--

--