DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Asynchronous JavaScript In Details
Vijay Kumar
Vijay Kumar

Posted on

Asynchronous JavaScript In Details

So let's see what is asynchronous JavaScript or generally asynchronous programming. Before we dive into the concept, we shall list the topics we gonna think about.

  • Thread
  • Synchronous
  • Asynchronous
  • Traditional Methods
  • Promises
  • Async/Await

This is the list and we gonna deep dive into one of the above-listed items. Let's start with the first one.


1.Thread

thread with a needle

What is a thread?

A thread is a process or part of a process. When there was the use of multiprocessor becoming popular and people needed more fast computers, then they try to develop a technique called threading a process or multithreading. Then what does the first sentence mean, right? Simply we can define a process as a heavyweight task or job where a thread is a subpart of a process and sometimes refers to as a lightweight process.


Single-Threaded

If there is only a single thread for a particular process then that process itself is a thread (called single-threaded) and this process will be running on a uniprocessor system (like a single needle with a thread). A uniprocessor system is a system which has only one single processor (CPU or central processing unit). That's mean every process contains at least one thread which is the process itself. JavaScript itself is an example of a single-threaded system.


Multi-Threaded

If there is a single-thread system then there should be its partner, a multi-threaded system. On a multi-threaded system, many threads run subsequently each on its own processor, then that computer system might be a multiprocessor system. It is like multiple threads in the hole of a needle. If a process is divided into multiple sub-tasks, then each of those sub-tasks is referred to as a thread. Java Virtual Machine (JVM) is an example of a multi-threaded system and most of the today computers are multi-threaded.

Since JS has only one thread, the main thread, the need for some kind of mechanism becomes vital to meet modern use cases. The concept of asynchronous programming in JS became popular using another thread called worker thread. But both thread can't work together since JS is single-threaded. I'll explain it in more detail.


2.Synchronous

Synchronous programming is what we do mostly. Most of the code we write work synchronously. let's see the following code example.

let firstName = "Vijay";
console.log(firstName);
alert("Synchronous");
let lastName = "Kumar";
console.log(lastName);
console.log(firstName + " " + lastName);
Enter fullscreen mode Exit fullscreen mode

How the above code will process? Firstly, the "Vijay" string will be assigned to the firstName variable and then it will be consoled. After that, the alert will be popped and at the same time open your browser developer tool to see that whether the line below the alert is processed or not until pressing the OK button of the alert box. The lastName variable will be declared and assigned with the string "Kumar" after the alert has been processed. Then the last two consoles will work. This step-by-step approach is called synchronous programming. This is mostly done in almost every programming languages. The main concept is one process or thread at a time.


3.Asynchronous

Where the asynchronous programming, two or more threads can be processed at the same if supported by the system. In the case of JS, there was an only the main thread but later there become a worker thread. The worker thread and main thread work independently of each other. The worker thread is also synchronous. That means the worker thread waits for some events to occur and does other remaining processing. By some events, I mean the event like fetching data like JSON or images and many other kinds of data from a server or a remote computer system.


4.Traditional Methods

The traditional methods were mostly used before the release of promises and other modern techniques. They are still being used today. So, what are these traditional methods? There are three methods we are going to talk about.

  • setTimeout()
  • setInterval()
  • requestAnimationFrame()

setTimeout()

All of the mentioned three methods are used in asynchronous programming. The first one is setTimeout(callback,timeInterval). This method accepts two arguments which are not avoidable. You can also add zero or more arguments behind the first two arguments. The first argument is a callback function. A callback function is a function expression that is passed as an argument in another function (in this case is the setTimeout()). The second argument is the time in a millisecond to wait before executing the callback function. The callback will be called after the specified time interval in a millisecond. We can add extra arguments after the second arguments. The new arguments starting from the third place until the end will be sent to the callback function as parameters to that function.

let firstName = "Vijay";
console.log(firstName);
let lastName = "Kumar";
console.log(lastName);
setTimeout(function(){
   console.log(firstName + " " + lastName);
},5000);
Enter fullscreen mode Exit fullscreen mode

First, the firstName is declared and assigned with the string Vijay. Then, the variable is consoled and the lastName variable is declared and assigned with Kumar. And then, it will also be consoled. Finally, the console statement in the setTimeout is processed after waiting 5000 milliseconds (5s) only once.

let firstName = "Vijay";
console.log(firstName);
let lastName = "Kumar";
console.log(lastName);
setTimeout(function(fName,lName){
   console.log(fName + " " + lName);
},5000,firstName,lastName);
Enter fullscreen mode Exit fullscreen mode

The above code example show that we can pass more than two arguments in the setTimeout() function. The arguments after the second arguments are passed as the arguments of the callback function.


setInterval()

This function is also similar to the setTimeout() function except for one thing. The setTimeout() function evaluates its callback function only once after waiting for the specified time in the second argument. Where, the setInterval() function execute the callback function more than once. Each execution takes place after waiting the time passed as the second argument in the setInterval() function. Simply timeout function executes its callback only once where interval function processes its callback function until close the browser or tab in which it's running.

let firstName = "Vijay";
console.log(firstName);
let lastName = "Kumar";
console.log(lastName);
setInterval(function(){
   console.log(firstName + " " + lastName);
},5000);
Enter fullscreen mode Exit fullscreen mode

The above code block executes the callback as same as the timeout one but setInterval processes the callback many time.

There is a way to cancel the execution of the above two set functions (setTimeout and setInterval). We can use clearTimeout() and clearInterval() to cancel or stop execution of the set functions respectively.
Both set functions return an identifier which we use to clear timeout and interval.

let firstName = "Vijay";
console.log(firstName);
let lastName = "Kumar";
console.log(lastName);
let identifier = setInterval(function(){
   console.log(firstName + " " + lastName);
},5000);
clearInterval(identifier);
Enter fullscreen mode Exit fullscreen mode

We can use clearInterval on setTimeout's identifier and vice versa, but this is not recommended and this is not a best practice.


requestAnimationFrame()

This method is mostly used in game development or animation in a browser or any web environment. This optimizes the web app performance if uses correctly. If we develop an animation, we can use requestAnimationFrame(). But the smoothness of the animation mainly depends on the unit called frame per second(FPS). Maybe you know this unit or maybe not, you have might be seen this unit in video related terminologies and in-game terminologies too.

const thousandCircles = () => {
   // This section contains codes to generate one thousand random circles
   requestAnimationFrame(thousandCircles);
}
thousandCircles();
Enter fullscreen mode Exit fullscreen mode

In the preceding code section, the requestAnimationFrame() method with parameter as its parent function which is thousandCircles() function. If we want to use a function then we need to call that function with require parameters passed in.


4.Promises

thread with a needle
Photo by Valentin Antonucci on Unsplash

A promise is another way of implementing asynchronous programming in JavaScript. Why do we need promise at all after having setTimeout,setInterval and requestAnimationFrame. But using the set methods we can face problems when we need to implement chain asynchronous codes or methods. It is inefficient to use set methods because they use callback functions. Take a look at the following example...

printBio(function(name){
   printFullName(name,function(age){
     printAge(age,function(bio){
       console.log(`Your name is ${name} and your age is ${age}. Your full bio is 
                   ${bio});
     },failCall());
   },failCall());
},failCall());
Enter fullscreen mode Exit fullscreen mode

The above code is an example of callback hell. The callback hell is happened when we nest many callback functions inside of others. This may lead to errors and many complications. So to solve the above problem, we have promise in JavaScript. JavaScript mostly used in chaining many asynchronous processes and callback functions. There are four stages in processing a promise.

  1. Pending - The promise is waiting for the result means the promise is currently processing.
  2. Fulfilled - The promise is processed successfully and has returned the result. Sometimes called resolved.
  3. Rejected - The promise is failed processing and has returned an error.
  4. Settled - The promise is processed but the promise might be resolved or rejected.

Let's see a code example for a promise.

printBio()
  .then(name=> printFullName(name))
  .then(age => printAge(age))
  .then(bio => console.log(`Your name is ${name} and your age is ${age}. Your full bio is ${bio}));
Enter fullscreen mode Exit fullscreen mode

The printBio function will be resolved or rejected, but we don't know when it will resolved or rejected. We can't even guarantee that whether the printBio function will be resolved or rejected. The above code processes only one promise at a time. U can implement multiple promises at the same time.First let's see another example of full promise code.

let promise = new Promise(function(res,rej){
  let x = 18;
  if(x){
    res();
  }else{
    rej();
  }
});
promise.then(// do something)
       .then(// do something)
       ...
       .catch(// do error handling);
Enter fullscreen mode Exit fullscreen mode

In the above code, first we create a new promise object and then pass a callback function with res and rej arguments. Then we do some processing in the callback function. After creating the object, we can attach as many then as we want for more data processing sequentially. The first then will be process when only the promise is resolved. Then another then will be processing. There can be attached any numbers of then into a promise(...). If some error is returned from the promise object, the catch part of the code will be processed. There is another code for the multiple promises.

Promise.all([a,b,c]).then(// do processing)
                    .then(// do processing)
                    ...
                    .catch(// do error handling);
Enter fullscreen mode Exit fullscreen mode

The above code will also be processed with the same manner as the single promise. The a,b,c in the array represents individual promise and then part of the code will only be processed when all of the given promises in the array are resolved. If any of the given promises is rejected, the whole promise block will be rejected and the catch part will be executed.

5.Async/Await

Async/Await is another new method to implement asynchronicity in javascript. As I said, this is relatively a new technique. What we actually do in this technique is we declare an async function and use await inside that function to perform the function asynchronously. So let's see what is async. async is a keyword which can be abbreviated as asynchronous, but we can only use async keyword in JS code not the asynchronous. We put it at the beginning of a function signature. The people who don't know what function signature actually is the line in the function declaration ( in case of javascript, that line is function funcName(parameters list...)). The keyword function and the function name and parentheses with parameters. So when we put async in front of a function, it will become async function funcName(parameters list...).

// Normal function
function calAge1(birthYear){
 return 2020 - birthYear;
}
calAge1; // this will return the function declaration or expression
calAge1(); // this will return your age

// Async function
async function calAge2(birthYear){
  return 2020 - birthYear;
}
calAge2; // this will return the function declaration with async keyword !!! Notice
calAge2(); // this will return a promise
Enter fullscreen mode Exit fullscreen mode

If you call any of the above function, the first one will return a number and the second one will return a promise. If you want to check, just open your browser developer console and try implementing the above code. After all, it is a great tool to learn JS. You might be thinking about how to use the return promise, then we can use the return promise by appending the then keyword. Let see below...

// Async function
async function calAge(birthYear){
  return 2020 - birthYear;
}
calAge; // this will return the function declaration with async keyword !!! Notice
calAge().then(alert); // this will directly alert your calculated age.
Enter fullscreen mode Exit fullscreen mode

What is await? It is a JS feature we can only use inside an async function. First, see the code below.

// Async function
async function calAge2(birthYear){
  return age = await Promise.resolve(2020 - birthYear);
}
calAge2; // this will return the function declaration with async keyword !!! Notice
calAge2().then(console.log); // this will return a promise
Enter fullscreen mode Exit fullscreen mode

The above function will also return a promise but only once the promise is either resolve or reject due to the use of await. The await will wait for the promise to resolve. Then the promise will be returned and logged into the console since we use then on the returning promise. Instead of calculating age, we can do many things with await. Mostly, fetching data from the server using fetch and all. If you wanna learn more, then Mozilla Developer Network is a great resource, try it.
=> Asynchronous JavaScript

This is the end of this article and I hope this will help the readers. During this lockdown, we can learn new things and try our concepts and theory in practice. You can learn new things and teaches them through articles, blogs and videos. Please stay home, stay safe, stay learn, do practice.

Top comments (0)

🌚 Life is too short to browse without dark mode