Before jumping on asynchronous javascript, let’s first write some code in synchronous javascript. By synchronous we mean that all the instructors are executing line by line as they are writte. From this blog onwards I would be writing code in ES6.
The above code is a synchronous code.
Now it’s time to add asynchronous code. For that let’s add setTimeout() function, which is used to set timer in javascript. It will help us to execute the code later.
SetTimeout() function accepts a callback function.
As this is the async javascript code, here the line 91 will be executed, then the focus will be shifted to second function. As there we are asking the code to wait for 2 seconds, rather than waiting for 2 seconds line 93 will run and javascript will wait for the execution of second function for 2 seconds in the background.
Therefore, below will be the output and second function will be executed after 2 seconds.
Behind The Scenes
We can use callbacks functions to defer actions into the future in order to make our code non blocking. There is another example of asynchronous javascript code. Let’s suppose we want to process a large image and do some actions on the webpage. The processing of the image can take time, therefore we cannot wait till that point. Therefore, the best practice is to use async code which will keep processing the image in the background and the user is able to perform actions.
Some feature of Async code
- Allow asynchronous functions run in the background
- We pass callbacks that run once the function has finished its work
- Non blocking
The above runtime environment is responsible how our javascript will run behind the scenes. Let’s look into detail how this environment works for asynchronous javascript.
First line 90 will run which run which is our first function. Therefore a execution context will be kept on top of our execution stack.
Then line 91(console.log) will be executed which will put up a Execution context log on top of the Execution context first(). First will be printed on the console and Execution context log will be poped out from the stack. Therefore our stack will look similar to this.
The next step is second function is being called. Therefore a new Execution Context is kept on top of stack. Next step is setTimeout() function is being called, and execution context of the setTimeout() is kept on top of the execution stack.
setTimeout() does not live in the javascript engine, it is available in the Web API which is a part of javascript runtime environment.
As soon as setTimeout() function is being called the timer starts running along with the callback in the Web API environment.
The callback function will not execute there, but it will keep sitting till the timer has finished and keep waiting in the asynchronous way.
The timer keeps working in the background, therefore we can keep executing our code.
Therefore Execution context setTimeout() and then Execution context setTimeout() gets popped out of the stack and setTimeout() waits there only.
Then line 93(console.log) will be executed which will put up a Execution context log on top of the Execution context first(). First will be printed on the console and Execution context log will be poped out from the stack.
Therfore till now we have executed our code synchronously and the setTiemout() keeps on working in the background.
Now as the timer has completed, only callback functions stays in Web API environment. Now from Web API environment the callback function comes to the message queue where it waits for the Execution stack to get empty for its execution.
Now Event Loop comes into picture. The job of the event loop is to constantly monitor message queue and execution stack. As soon as the execution stack is empty, the event loop will push the callback to the execution stack.
Then line 85(console.log) will be executed which will put up a Execution context log on top of the Execution context callback(). First will be printed on the console and Execution context log will be poped out from the stack and then in the end Execution context callback() will be poped out of the stack and our stack will be empty again.