Overview
In this blog, the main focus is on understanding call stack, web API, callback queue, job queue, and event loop for beginners in javascript and deep dive into learning about how they work, why we need them, and the connection between all these things.
Let's start, As Javascript is a synchronous single-threaded language means
Javascript can "only execute one command at a time in a specific order" as it can only go to the next line once the current line has been finished executing.
Whenever you run a javascript code. JS engine will create a call stack and execution context. Now, let's know about the call stack
Callstack
Javascript has one call stack and it is present inside the Javascript engine.
It handles everything to manage this execution context creation, deletion, the control and it manages a stack. This is known as the call stack.
Mainly call stack maintains the "order in which execution contexts are carried out".
Let's understand this call stack and execution context with the example :
Here we can look into the execution of the above code by the JS engine, it was as shown in the below image
When you run JS code, the JS engine will create a call stack and execution context in that. This execution context is created in two phases:
1. Memory creation phase (variable environment)
2. Code execution phase (Thread of execution)
In the memory creation phase, javascript will allocate memory to all variables and functions.
In the code execution phase, code is executed one line at a time.
So here in the above example, In the execution context, the memory creation phase stores a special value known as "undefined" for variables for functions it stores the whole code.
In the code execution phase, The value will be assigned to a variable and
when you invoke a function a brand new execution context will be created and there once the code execution and evaluation of values are done. Now it returns the control of the program, to the place where this function was invoked.
As soon as we return the value there won't be execution context (will be deleted)
So once JS completes all its work, the program is finished. The whole global execution context also delete.
So far we see synchronous code and their execution in the call stack, but how the asynchronous code will work in javascript? As javascript is synchronously single-threaded, do we need to wait when encountering fetch API call, setTimeout functionality until it completes to move on to next line of code or it will block the code execution..... No, so here in Javascript they will execute in different ways, web APIs and callback queue, and job queue will handle asynchronous code.
Web API
These are different APIs provided by the web browser that helps you build web applications.
A few that you might be familiar with are:
setTimeout()
setInterval()
fetch()
DOM APIs
Read more about Web APIs here: https://developer.mozilla.org/en-US/docs/Web/API
Callback Queue or Task queue
The Callback queue is a data structure that operates on the FIFO (first-in-first-out) principle. Callback functions that need to be asynchronously executed, are pushed onto the callback queue. These are later pushed to the Call stack to be executed (when the event loop finds an empty call stack).
How do WebAPI and Callback Queue work together?
Let's understand them, by an example
:
Here the output will be:
Did you notice the delay in printing the Second statement
?
Here is the flow of code, and how it executes
In the code first, all code will go in the call stack and global execution context,
whenprintFirstStatement()
invokes, creates a new execution context and performs the task, and prints the output.when
printSecondStatement()
invokes, the call stack finds it as webAPI so it moves code to webAPI(here is setTimeout()) once it completes wait for certain seconds and move to the callback queue. At this time event loop will check whether the call stack is empty, so if it's not empty it will wait until it completes all tasks and move the callback to the call stack for further execution.when
printThirdStatement()
invokes, in the call stack it creates a new execution context and performs the task, and prints the output meantime the printsecondStatement function was in the callback queue, the event loop will check call stack is empty, and move to the callback from the callback queue to call stack and print the output.
Job Queue or Microtask queue
Job Queue reserved only for new Promise()
functionality. So when you use promises in your code, you add.then()
method, which is a callback method. These thenable
methods are added to Job Queue once the promise has returned/resolved and then gets executed.
Job Queue has higher priority than callback queue.Example:
Here in the image, we can see the flow of code
The JS engine will create a call stack, global execution context, and
promise function
invokes new execution context will be created here as it finds it returning apromise
.promise
will return aresolve
orreject
state.
Once it getsresolve
orreject
state, the callback function in.then
or.catch()
will move to the job queue.The event loop gets the task in the job queue, so it checks the call stack is empty, if it is empty it will move the task further the execution, if not it will wait until the call stack will be empty.
The last call stack will print the output and the execution context of the function will be deleted and the global execution context will also delete.
Event Loop
It will be running continuously and checks the call stack(main stack), if it has any code to execute, if not then it checks the callback queue, if the callback queue has codes to execute then it pops the code from it to the call stack for the execution.
If any code is there in the job queue, the event loop will pop the code from the job queue to the call stack and then take the callback queue code.
Conclusion
Javascript has one call stack and it is present inside the Javascript engine.
Mainly call stack maintains the "order in which execution contexts are carried out".JS Engine creates a call stack and global execution context when it runs a code,
and whenever a function invokes new execution context will be created.Asynchronous code execution will be handled by the web APIs and callback queue(task queue).
Job queue(microtask queue) is reserved only for promises in javascript, it has higher priority than the callback queue.
The event loop continuously monitors between call stack, callback queue, and job queue
Thanks for reading it๐. I hope it was insightful and you got to learn something new today. If you liked the article, please post likes and share it in your circles. Share your feedback and comment away.
Let's connect on Twitter. I'd love to connect :)