The Art and Science of Async/Await: Concurrency in JavaScript published 9/7/2023 | 3 min read

This article was ai-generated by GPT-4 (including the image by Dall.E)!
Since 2022 and until today we use AI exclusively (GPT-3 until first half of 2023) to write articles on!

Handling asynchronous processes in JavaScript can often lead to complex, convoluted code filled with nested callbacks. However, emergence of Promises and, more recently, the Async/Await syntax have simplified managing asynchronicity.

In this post, we'll delve into the magic of Async/Await, discover how it simplifies handling asynchronous operations, making your code cleaner, more readable, and easier to manage.

Promises Recap

Before diving into Async/Await, it's important to cover the basics of Promises. A Promise in JavaScript represents an operation that hasn't completed yet, but is expected in the future. When the operation completes, the Promise is either fulfilled or rejected. Using Promises, you could write an asynchronous HTTP request as follows:

  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Async/Await: A Cleaner Approach

Async/Await is a modern syntax of handling promises in a more comfortable synchronous-like manner. It is syntactic sugar built on top of Promises. To mark a function as an asynchronous, you prefix it with the async keyword. The await keyword can only be used inside an async function and makes JavaScript wait until that Promise settles and returns its result.

Here is the equivalent of the above code using Async/Await:

async function fetchData(){
  try {
    const response = await fetch('');
    const data = await response.json();
  } catch (error) {
    console.error('Error:', error);

This is simpler, more readable, and less error-prone. Error are easier to handle too, as they can be caught using standard try/catch syntax.

Concurrency with Async/Await

So what about concurrency? We often need to do several asynchronous operations at once, and Async/Await has that covered too. You can run Async operations in parallel using Promise.all():

async function fetchMultipleData(){
  try {
    const [response1, response2] = await Promise.all([
    const data1 = await response1.json();
    const data2 = await response2.json();
    console.log(data1, data2);
  } catch (error) {
    console.error('Error:', error);

This way, both fetch operations are started simultaneously, and the total wait time is minimized. We wait for both responses to be complete, and then process the results.


Async/Await in Javascript has brought significant improvements to handling asynchronous operations. It delivers cleaner, more readable code simplifying the management of asynchronous processes. However, it is essential to keep in mind that Async/Await is not a replacement for understanding Promises. It's an abstraction built on top of Promises, and understanding Promises will help you grasp Async/Await better. Happy coding with Async/Await!

You may also like reading: