Asynchronous Programming in JavaScript

Best use of Async/Await

sampath kumar gajawada
Level Up Coding

--

The only way to learn a new programming language is by writing programs in it — Dennis Ritchie

Asynchrony in computer programming refers to the occurrence of events independently of the main program flow and ways to deal with such events.

Image by Nathan Anderson on Unsplash

Unlike programming languages Java/C#, JavaScript is a single-threaded and all code is executed in a sequence line by line, not in parallel. Usually, we would like to have the occurrence of events that should be independent of the main program flow. This can be achieved in JavaScript using call-backs, Promises, async/await.

Async/await is a new way to write asynchronous code, other alternatives for asynchronous code are call-backs or promises.

Async/await makes asynchronous code look and behave little like synchronous code.

In this article, I will try to address

  1. What is Async/Await
  2. Working of Async/Await
  3. Concurrency with Promises
  4. Parallel Execution with Async

Async

The async function declaration defines an asynchronous function, a function that returns an object. These functions enable us to write a promise-based code without blocking the execution thread. They operate in a separate order than the rest of the code via the event loop, returns a promise as its result.

async function GetText() {
return ”Hello”;
}

GetText().then(alert); // Hello

If you observe the above running GetText() returns a promise and called using then.

Await

An async function can contain await expression, await pauses the async execution until an associated promise is resolved. Await makes the async block wait but not the whole execution block. Await can be used only in async functions.

function getData() {
return new Promise(resolve => {setTimeout(() => {resolve(‘resolved’);}, 2000);});}
async function asyncGet() {console.log(‘calling’);
const result = await getData();
console.log(result);// expected output: ‘resolved’}
asyncGet();

By running the above code, we can observe that the async function code is being paused for 2 seconds because of the await keyword. Once the getData() promise is resolved, we could see the desired output in an async function.

We are too much worried about syntax and its cool. Let us dig deeper with example and start playing with async/wait.

Working of Async/Await

Throughout this article, we will use an example of instructions for making lunch to see how async/await make it easier about a series of asynchronous operations. Here is the list of instructions to make lunch.

Image by Jakub Kapusnak on Unsplash

1. Pour Spicy Peanut soup.

2. Prepare Vegetable Salad.

3. Prepare Scrambled Egg.

4. Fry Burger buns.

5. Add Veggies to Burger.

6. Pour a glass of lemon juice.

If you have experience with making lunch, you would execute these instructions asynchronously. Cooking lunch is a good example of asynchronous work that isn’t parallel. One person (or thread) can handle all these tasks. In the lunch analogy, one person can make lunch asynchronously by starting the next task before the first completes. The cooking progresses whether someone is watching it. As soon as you start cutting vegetables for the salad so, you can do a scrambled egg. Once the scrambling starts, you can fry the buns on a pan.

Let’s write all the instructions in JavaScript.

Sequence

JavaScript doesn’t interpret those instructions the same way people do. The JavaScript will block on each statement until the work is complete before moving on to the next statement. That creates an unsatisfying lunch. The later tasks wouldn’t be started until the earlier tasks had completed. It would take much longer to create the lunch, and some items would have gotten cold before serving.

If you want to execute those instructions asynchronously, one should write asynchronous code.

The preceding code demonstrates a bad practice: constructing synchronous code to perform asynchronous operations. As written, this code blocks the thread executing it from doing any other work. Let’s start by updating this code so that the thread doesn’t block while tasks are running. The await keyword provides a non-blocking way to start a task, then continue execution when that task completes.

Asynchronous

The above code doesn’t block while the salad or the scrambled egg is cooking. This code won’t start any other tasks though. You’d still fry the buns on the pan and stare at it until it was fried. But at least, you’d respond to anyone that wanted your attention. Now, the thread working on the lunch isn’t blocked while awaiting any started task that hasn’t yet finished.

Concurrency with Promises

In many scenarios, you want to start several independent tasks immediately. Then, as each task finishes, you can continue other work that’s ready. Promises enable you to write code that more closely resembles the way you’d create lunch. You’d start making the salad, scrambled egg, and fry the bun at the same time. As each requires action, you’d turn your attention to that task, take care of the next action, then wait for something else that requires your attention.

You can create a promise for each task and await each task before working with its result.

Concurrency

If you observe the above code, you can start all asynchronous tasks at once and await each task only when you need the results. This is like code in building a web application that makes the request of several web APIs, then combines the results into a single result.

This code is asynchronous and is the same way how a person can cook lunch.

Parallel Execution with Async

Async await makes execution sequential, but it can be made faster with parallel execution using Promise.all.

In the above example, we can see that preparing salad, scrambled eggs and bread are independent of each other and can be executed parallelly.

Usual Approach

async function do() {
await saladPromise; // Wait 50ms
await sEggPromise; // then wait another 50ms.
await burgerPromise; // wait for 50ms
return “done!”;
}

The above code takes 150ms of time and a huge time for a well-built web application. This is because all the promises are executed in a sequence one after the other, sEggPromise can be done only after saladPromise.It is not a good practice and time-consuming.

We can overcome the above challenge using Promise.all().

Using Promise.all

The Promise.all() method returns a single Promise that resolves when all of the promises passed as an iterable have resolved or when the iterable contains no promises. It rejects with the reason for the first promise that rejects.

Wrapping Up

Async/Await is the new feature introduced by JavaScript to write your asynchronous code as easy as you write synchronous code. It also gives the feasibility to execute the functions in parallel and concurrent ways. You can start implementing this feature when you are retrieving data from web API or loading any images or any asynchronous use case.

So far we saw more about Async/Await, and its summed up with Promises. Please go through the below article for a clear picture of promises.

Hope you enjoyed it !!! Please do comment on any queries or suggestions !!!!

--

--