Skip to main content

Command Palette

Search for a command to run...

Async/Await in JavaScript

Updated
2 min read

As a Javascript developer, you have seen the application become more interactive and started handling more asynchronous operations like API calls, file readings, and timers.

Initially, developers rely heavily on callbacks, the promises start improving the situation, and finally, async/await code make easier to handle the asynchronous operations.

In this article, you'll learn:

  1. Why async/await was introduced

  2. How async functions work

  3. The concept of the await keyword

  4. Error handling in async code

  5. Comparison with promises

  6. Execution flow

Why Async/Await Was Introduced

Before async/await, developers mainly used:

  1. Callbacks Promises
    Callbacks often led to deeply nested code, sometimes called callback hell.

    getUser(function(user) { 
        getPosts(user.id, function(posts) { 
            getComments(posts[0].id, function(comments) {
                console.log(comments);
            });
        });
    });
    
  2. Promises improved this by flattening the structure:

    getUser()
      .then(user => getPosts(user.id))
      .then(posts => getComments(posts[0].id))
      .then(comments => console.log(comments))
      .catch(error => console.log(error));
    

    While promises were cleaner, chaining multiple .then() calls could still become difficult to read.
    That’s why async/await was introduced. It allows asynchronous code to look almost like synchronous code.

Async/Await Is Syntactic Sugar

async/await is basically syntactic sugar over promises.

That means it does not replace promises internally. It simply provides a cleaner syntax for working with them.

This:

async function example() {
    return "Hello";
}

Is internally similar to:

function example() {
    return Promise.resolve("Hello");
} 

How Async Functions Work

An async function always returns a promise.

async function greet() {
    return "Hello World";
}

greet()
  .then(console.log);

// Output: Hello World

Even though we returned a string, JavaScript automatically wraps it inside a promise.

Basic Async Function Example

async function fetchData() {
  return "Data received";
}

fetchData().then(result => {
  console.log(result);
});

// Output: Data received

Understanding the Await Keyword

The await keyword pauses the execution of an async function until a promise resolves.

function delay() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Done!");
    }, 2000);
  });
}

async function run() {
  const result = await delay();
  console.log(result);
}

run();

// Output after 2 second: Done!

How Await Improves Readability

Without await:

fetchUser()
  .then(user => {
    return fetchPosts(user.id);
  })
  .then(posts => {
    console.log(posts);
  });

With async/await:

async function showPosts() {
  const user = await fetchUser();
  const posts = await fetchPosts(user.id);

  console.log(posts);
}

The second version looks much more natural and easier to follow.

JavaScript: Beginner to Advance 🚀

Part 1 of 21

This blog series is designed for professionals who want to learn JavaScript step by step. Starting from the basics like variables and data types, we gradually move to functions, DOM manipulation, and real-world mini projects.

Up next

Error Handling in JavaScript: try, catch, finally

While writing a Javascript code, no matter how carefully you have written the code but once the user input a invalid data and the API fails, the application might crash at runtime due to some edge cas

Async/Await in JavaScript Explained for Beginners