Javascript engine runs code line by line which we call synchronous behavior, there's another type of execution that javascript engine does is known as asynchronous javascript
. Before jumping into the beautiful world of asynchronous
we must understand why we require this type of execution.
when you write code sometimes there is a function whose input depends on another function's output. but if other function takes time to give you the result then what will you do in meantime except waiting which is a very bad practice. In the case of the web when we call API
for data it usually takes time to return it is a very frustrating experience for the user if he had to wait until the response comes and do other stuff that can be done in meantime.
A real example for this in your Pc you can open multiple programs and your system don't mind because it has multiple processors it shifts load among them and how is it done? well, you can imagine, it is asynchronous which allows us to run the program in the background.
For understanding the asynchronously javascript.
we need to make a mental model
in our head to understand what's going on behind the scenes and how the javascript engine
executes our code.
In ES6
async functions
were introduced for this purpose. let's start with a very basic async function
example for making our mental model.
async function createFlow(){
console.log('Me first')
const data = await fetch('https://twitter.com/tashfeen/tweets/1');
console.log(data);
}
createFlow();
console.log('Me second');
Do you have any idea what will be print on the screen? well, let's figure out the answer. First, we want to visualize how this code will execute on the javascript engine.
Javascript engine consists of three main elements
1 Execution context
2 Memory
3 call-stack
The execution context runs the code and displays it on screen. Memory stores variables functions etc. call-stack runs functions in first in last out principle. At the bottom, there is another type call queue-stack that holds those functions that wait for some browser work to finish.
Now you get your visualization. let's see how it gonna be executed our code.
async function createFlow(){
console.log('Me first')
const data = await fetch('https://twitter.com/tashfeen/tweets/1');
console.log(data);
}
At the first line of code, we have a function expression. It will store function definition at Memory
and goes to the next line.
Next line is invoking createFlow() function.
createFlow();
Javascript engine first looks into the global Memory
is there any function with the name of creatFlow()? yes, it found one then it will put this function inside call-stack and It will create its own execution inside of the global Execution context. Now it start executing function's code line by line.
console.log('Me first');
this will be print on the screen. then it goes to the second line which's a variable definition.
const data = await fetch('https://twitter.com/tashfeen/tweets/1');
It will store the data
variable in Memory.
Its value is blank in Memory
right now. The right side of this variable invokes browser's facade function fetch()
which triggers web browser feature work to get the data from the twitter server. fetch()
will return promise object which has two things value
and onfulfillment[]
. When the response comes from the server it fills the value
. If there is some work to be done on this value
it will be done onfulfillment[].
For visualizing this process, I made a diagram.
Browser background work takes time to get back with data. How we will console.log(data)
when we don't have data? Are we going to sit idle and wait for a response? You are right, the answer is NO. But how we execute the rest of the code. Well In the above code you saw special browser feature await
which will through us out of function's execution context, and put creatFlow function in queue-stack. Now it came to global execution context and execute next line in code
console.log('Me second');
It'll print Me second
on screen. Now there's no other code left for execution.
I am glad that you asked what happened to our
console.log(data)
How will we go back inside of the createFlow()
execution context?. Well, when we get a response from the twitter server
It'll fill the value
property of promise
object and put createFlow()
on call-stack and start executing where it left earlier. which is
We got our data from the twitter server.
which is a string with simple HI
It fills value
property of promise
object and stores this value = 'HI'
in Memory
of function's execution context.Now Javascript reads
console.log(data)
Javascript looks for data
variable into the Memory
and found with data = 'HI'
Which will be print out on screen after about 200ms
.
This is asynchronous we left some code for running in background which requires some time to finish. We get back to other code and start executing it. When we got our response we execute left code. Now the execution cycle is complete.
Top comments (0)