Knowing How Javascript Execute Its Codes

Knowing How Javascript Execute Its Codes

Have you wondered how javascript's code is executed?

I woke up Saturday morning, and out of nowhere, I was thinking, how does javascript execute hundreds of hundreds of code in such a fast time. So just like an average person, I go to my PC, start googling and watching some explanation for hours, and this is I'm here to share what I got.

Javascript is a single-threaded language

Do you know that our brain is not able to do multitask? Except for a tiny percentage of people, When we think we’re multitasking, most often, we aren’t doing two things at once. Still, instead, we’re doing individual actions in rapid succession or task-switching. Single-threaded language like Javascript does the same thing. It stacks up a list of tasks and executes them one by one. That stack has a name, and it is "Call Stack".

callstack_async.drawio.png

From the top, code is inserted per task, and if a task is a function and has another task in it, it will push into the stack. Once one set of processes is pushed in, Call Stack will consume it in a LIFO manner. The last task pushed will be the first one to be consumed.

callstack_async_2.drawio.png

When one set of processes in this case function is finished, Javascript Runtime will continue to execute the rest of the codes.

How About Promises?

If you know Javascript and build some kind of application, 9 out of 10, you already know about Promise.

What is Promise

Maybe you already wrote it but didn't know that your code is Promise, so let us start with an example.

async function getUser() {
  const res = await axios.get('/user')

  return res.body
}

HTTP Request is a common thing we do when we build Web Apps. In that example, we get user data from the backend end to return its content.

Let us test that function.

const user = getUser()
console.log(user)

We expect it to log out user data. But here, the output says otherwise.

undefined

It happens because we don't until our data is fetched. To fix it, we insert await at declaration.

const user = await getUser()
console.log(user)

And the output is as we are expected.

{
  name: 'Alvin'
}

Promise in Javascript is an object that may produce value in the future. Since JavaScript is an asynchronous language, the following process will be executed without waiting to complete the previous one if the previous execution takes a long time. But if we wait for Promise to end with await, we get our expected value.

The question here is, "How does javascript do something asynchronously while itself is single-threaded?".

Javascript concurrent-like process

I know it's a little bit misleading, but while javascript runtime can only do one thing simultaneously, the browser does not only consist of javascript runtime.

WebApis

To make it simple, WebApis is where asynchronous code is executed. When code contains an asynchronous function, the code is then pushed to Call stack. Call Stack know it is an asynchronous task and throw it to WebApis. WebApis and then process it and throws callback into Callback Queue.

WebApis also contain DOM and also handles user interactions. For example, when the user clicks a button, WebApis throws a click callback into Callback Queue.

Callback Queue

Callback Queue is a queue of tasks thrown by WebApis. Tasks will later give back to Call Stackand be processed.

Event Loop

The process of moving tasks from main code to call stack, callback queue back to call stack is the event loop. Event Loop stops when the call stack processes something and loop when there are no tasks left. Javascript will execute all main code processes in that logic before touching Callback Queue.

Executing

Let's get a better image of it. We start with simple code, the same as before, rather than only logging strings. We try to make an async request, fetch a user, and log out the user name.

callstack_async_1.drawio.png

Event Loop will start its loop at the call stack and process the main code as before. We have an async function, so instead of processing in the call stack, it will be thrown to WebApis to be executed there.

callstack_async_1.drawio.png

It will continue until codes and stacks are processed. When WebApis is done executing, it will throw a callback in the Callback queue. In this case, it's logging out the user name.

callstack_async_1.drawio.png

After that, Event Loop will start looping between Callback Queue and Call Stack. If there are tasks in Callback Queue, It will throw it to Call Stack and execute it later when the event loop stops at Call Stack.

callstack_async_1.drawio.png

Ending

I hope you get the big picture of how javascript runs in our browser. If you are interested in more, I suggest you watch this video; it's the easiest-to-understand video, in my opinion.

Youtube Link

Did you find this article valuable?

Support Alvin Endratno by becoming a sponsor. Any amount is appreciated!