Hey folks! I have been learning about javascript lately. I came across a lot of terms like v8, DOM, callbacks, stack, etc. So in this article, we are going to look at how javascript works internally and supports asynchronous calls when it is synchronous. Why thinking asynchronous is important?
The above diagram shows actually how javascript is executed in the browser. So now let's divide the above diagram into parts and see what each of them exactly does.
1. v8 engine -
- Any programming or scripting language requires the bare machine to run. Consider when we run our c/c++ code or golang code, they've got compilers. Compilers convert them into machine code and then machine code is executed by processors.
- So JS also requires some means through which the browser understands JS code.
- v8 is a JS engine that was developed for chromium-based browsers and written in c++.
- This is responsible for running JS and code execution in browsers. Call Stack and heap is part of v8 that helps JS to execute commands.
2. Heap -
- Heap is the memory area where memory management of JS code happens.
- This is where variables and functions are stored in form of objects by JS.
3. Call Stack -
- We have come to the exciting part now. This is where JS code is actually executed in the code execution phase.
- We know, JS is interpreted language. So JS is executed line-by-line.
- Let's see an example.
- Do you know how would call stack execute it? Let's see.
- Before we start talking about the stack, let's just understand how execution starts.
- Whenever JS starts execution it always happens in 2 phases. Memory Creation and Code Execution.
- In the memory creation phase, the whole code is checked. Variable and function declarations are hoisted.
- After memory creation, in the code execution phase initialization of variables and calling of function happens.
- So coming back to the above example, when the interpreter reaches line one, sees a console.log statement, pushes this statement on the stack.
- As we know stack is last-in-first-out, interpreter waits until this statement executes. Once it finishes 2 things are done. First, the previous statement on stack is popped from call stack and then it moves to line no 3 and finds a function declaration.
- Since it's not invoked, interpreter moves to line no 7. Here printName is invoked so control goes back to line no 3 and this function would to pushed in stack now. now this function has a console.log() statement. So that also pushed to stack.
- Once the console is logged, the previous 2 items on call stack i.e. console.log() and function printName() would be popped respectively.
- So this is how code execution occurs in JS. So a quick summary - Statements are pushed onto stack, program control waits until execution of top item on stack finishes since JS being single-threaded in can not move furthers until the current line of execution happens and then moving on to next statement;
- It makes sense right? that's why javascript is synchronous single-threaded language.
4. WebAPIs -
- The WebAPIs aren't part of v8. They are provided by browsers. That means WebAPIs are available to each browser you are working on.
- DOM actions, fetch() request, XML objects and other functions like setTimeout() aren't part of v8 but they are given to us via WebAPIs that are incorporated with browsers.
- Till now we were saying that JS is synchronous, right? No?
- But WebAPIs are part of browsers that helps JS to make it asynchronous. We would come here why does it make JS asynchronous? in the next part of this article
5. Callback Queue -
- Whenever some WebAPIs are called or any DOM event happens, that event triggers a function that acts as a utility function to perform tasks after that event. This function is usually known as a callback function.
- Since they trigger after the event, they aren't pushed to call stack but they are queued in callback queue to wait until being pushed on the call stack.
- Asynchronous calls also return callbacks or promises that are queued right here in the queue.
6. Event Loop -
- As we discussed in above section that callbacks aren't pushed on call stack but are queued in the callback queue.
- So how would callbacks waiting in queue know that it is my turn to go on stack and finish the job instead of waiting here. They need a way, aren't they?
- This is where the event loop plays the role.
- The only job of event loop is
Wait until call stack is empty. If call stack is empty push one callback onto stack and start waiting until the call stack is empty again
.
So we've covered the parts that help JS to execute and saw why JS is synchronous and single-threaded. In next part, we would see why synchronous nature of JS is not good and what are harms of it.
See you in the next part.😃
Top comments (0)