Asynchronous Programming: Part 1(Basics of Asynchronous JavaScript)

Arpit Pundir
HackerNoon.com
Published in
6 min readJun 23, 2019

--

In this blog posts series we are discussing one of most difficult topics of javascript, famously called “asynchronous javascript”.If you have basic understanding of javascript syntax then you are good to go for this series. We would be covering everything relevant there is for complete understanding of asynchronous programming.

One last thing before starting, there are many code snippets in this series, it would be very helpfull to you if you fire up your machine and play with code yourself, it would speed up your understanding and you will have a hand on practice with code.

Asynchronous Programming

setTimeout(arg1, arg2): setTimeout() is an inbuilt function that is used to execute some given code after a given time. arg1 is your code in form of a function that you want to execute and arg2 is time in milliseconds after which you want your code(arg1) to execute.

Expect output for code below and then run in your machine.

console.log(“I am first”);console.log(“I am second”);console.log(“I am third”);//output1
I am first
I am second
I am third

Now for this one

console.log(“I am first”);setTimeout(function(){console.log(“I am second”);}, 2000);console.log(“I am third”);//output2
I am first
I am third
I am second

output1 and output 2 are different, why? This is because we have introduced asynchrony in our second part of our code by using setTimeout() function i.e second snippet has two parts one is “now”, the code that will execute now

console.log(“I am first”);setTimeout(function(){...}, 2000);console.log("I am third");

another is “later”, this code will execute later i.e after two seconds.

console.log(“I am second”);

Any code that can not execute now will execute asynchronously i.e jsEngine will give “later” part of our code to one of the WebApi that browser provides. This WebApi will inform our environment when two seconds have completed so that js runtime can execute arg1 function. While WebApi is executing our “later” part of code jsRuntime will keep on executing “now” part of code and we see “I am third” before “I am second” because jsRuntime executes line third before WebApi returns response for our setTimeout() function. This parallel looking execution of code is called asynchronous. But mind you js is single threaded which means jsRuntime is executing only one thing at a time. We will go more deep in how all of this is happening but before that let’s learn to set up connection between our application and server via requests.

Making Request to the server

You might already be familiar that in most of our web applications we are using data that is not available on our machine but coming from a database that is don’t know where, be it facebook, medium, insta whenever you open your feed, data you are seeing is coming from a non local source, so how is this all happening. This is clear that we are sending some information to our server about what data do we need and then server checks , if we have permission to access requested data then it returns our data otherwise it neglects our requests.

We communicate with server via objects of type XMLHttpsRequest, despite its name it can be used to access all kinds of data.

const request = XMLHttpRequest();// XMLHttpsRequest() is a constructor which initializes our variable request with an objectrequest.open("GET", "http://puzzle.mead.io/puzzle?wordCount=3");//We are calling a method open(), first argument specifies the type of request, second argument is an API of source of our data,this source returns a random puzzle request.send();//send() method sends our requests to the server

What happened to our request, how do we know that it has data that we requested or it has failed? let’s look at that next. readystatechange is an event that triggers whenever state of our request changes. readyState and status are two properties which can be used to check whether our request is sucsessfull or not, refer to mdn docs to know more about them

request.addEventListener(“readystatechange”, (e) => {if(e.target.readyState === 4 && e.target.status === 200){const data = JSON.parse(e.target.responseText);//responseText property of our request has response in form of json text and we use JSON.parse() method to parse json.console.log(e.target);  }else if(e.target.readyState === 4){

console.log("Error");
})

Why asynchronous

Now you know how to make request and get data back. If you have run previous section code than you must have noticed that request take some time to return response, this time depends on many factors.

So if i am making requests for two puzzles synchronously next request will proceed only after we have got response from previous request so if one request is taking a single sec then both our request would take 2 sec for completion, for that time your UI would get blocked and user will get frustrated.

Asynchronously, due to distribution of requests among diffrent WebApi we do not have to wait for our first request to complete , to start our second request. We would start our first request hand it to the webApi then we would start our second request, hand it to another webApi and then keep executing code without waiting for response from requests. We have not changed the server processing time for a request by using asynchronous programming, it is same in both cases. But waiting time of both requests is being overlapped which reduces total time significantly if we have large no of requests. That’s why asynchronous is the default way of making http requests.

Under the hood: Event Loop, callback queue and stack

Since js is single threaded i.e js runtime will execute single piece of code at any time, so how does it decide, when to print the response that we got back from server. Your answer might be, at the instant when it got back the response, but what if jsRuntime is executing some code that comes after those requests in our file at the same instant, how does it decide what to do.

Let’s solve this problem with an example, what should be the output of the below code

console.log(“starting”);setTimeout(() => {console.log(“waiting 1”);}, 2000);setTimeout(() => {console.log(“waiting 2”);}, 0);console.log(“stopping”);//output
starting
stopping
waiting 2
waiting 1

You must be wondering that even though the wait time for second setTimeout() function is 0 sec, still it is printing after “stopping”. It is because of stack, callback queue and event loop.

Stack is a place where our function calls are ,function at the top of stack is executed first and a new function call is placed always on the top of stack.

When we get response back from a request or in this case when time specified in setTimeout() is over, response function do not go directly in the stack but it would be placed in a queue called callback queue. This queue stores responses in a way such that response that came first would go first in stack for execution.

Our callback queue will start sending responses to stack only when stack is empty. Event loop is responsible for informing callback queue that stack is empty.

Initially first console.log() call is placed in stack, it will execute and would be removed from stack then first setTimeout() call is placed in the stack, since it is an async call and we know WebApi deals with async calls so it is removed from stack and browser is responsible for placing the response of this async call in the callback queue after 2 sec from now, now again stack is empty so second setTimeout() call is placed in the stack and this too would be send to browser and last console.log() call is placed in the stack. it gets executed and we see “stopping” on our console.

Now it is clear that response from second setTimeout() call is still in callback queue, in the mean time last console.log() gets executed and we see “stopping” before “waiting 2”.

Response from first setTimeout() call comes in callback queue even after response for second setTimeout() call so it goes in stack at the end and we saw “waiting 1” at the end.

We have covered enough for this blog, but we are just starting, there is much more to cover. In next blog we would be talking about Callbacks and Closures.

--

--