# Async/Await in JavaScript

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.
    
    ```javascript
    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:
    
    ```javascript
    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:

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

Is internally similar to:

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

## How Async Functions Work

An async function always returns a promise.

```javascript
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**

```javascript
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.

```javascript
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`:

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

With `async/await`:

```javascript
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.
