# Async/Await in JavaScript

You've met promises. You understand `.then()`. You've chained a few calls together and it mostly worked. But then you needed to do three async things in sequence, and you ended up with something like this:

```javascript
getUser(userId)
  .then(user => {
    return getOrders(user.id);
  })
  .then(orders => {
    return getProduct(orders[0].productId);
  })
  .then(product => {
    console.log(product.name);
  })
  .catch(err => {
    console.error(err);
  });
```

It works. But it reads sideways. Each `.then()` is a new indentation, a new callback, a new mental context to hold. You can't easily share variables between steps without hoisting them outside the chain. Error handling applies to the whole chain but it's tacked on at the end, invisible until something breaks.

`async/await` was introduced in ES2017 to fix exactly this. Not by replacing promises by giving you a way to write promise-based code that looks and reads like regular synchronous code.

## Syntactic sugar over promises

The first thing to understand is that `async/await` is not a new async system. It's a new *syntax* for working with promises. Under the hood, every `async` function returns a promise. Every `await` pauses execution and waits for a promise to resolve. No new engine magic just a cleaner way to write what you were already doing.

Think of it this way. Promises gave you a contract: "this will eventually have a value." `async/await` gives you a way to write code as if that value is already there, and JavaScript handles the waiting behind the scenes.

## The `async` keyword

Putting `async` before a function declaration does one thing: it makes that function always return a promise. Even if you return a plain value, JavaScript automatically wraps it in a resolved promise.

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

greet().then(msg => console.log(msg)); // "Hello!"
```

You returned a string. But because the function is `async`, the caller receives a promise that resolves to that string. That's the contract.

You can use `async` with any function style:

```javascript
// function declaration
async function fetchData() { ... }

// arrow function
const fetchData = async () => { ... }

// method in an object
const api = {
  async getUser() { ... }
};
```

## The `await` keyword

`await` can only live inside an `async` function. It pauses that function's execution until the promise it's waiting on resolves then hands you the resolved value directly.

```javascript
async function loadUser() {
  const user = await getUser(1); // pauses here until resolved
  console.log(user.name);        // then continues
}
```

Without `await`, `getUser(1)` returns a promise object not the user. With `await`, you get the user directly, as if the function was synchronous. The pause is real but it's non-blocking: while this function is waiting, JavaScript keeps running everything else.

Here's what that promise chain from earlier looks like rewritten with `async/await`:

```javascript
async function loadProductFromUser(userId) {
  const user    = await getUser(userId);
  const orders  = await getOrders(user.id);
  const product = await getProduct(orders[0].productId);

  console.log(product.name);
}
```

Top to bottom. Left to right. Each line waits for the previous one before moving on. No callbacks. No indentation staircase. It reads like a recipe: get the user, get their orders, get the first product, show its name.

Here's the execution flow when you call an `async` function:

![](https://cdn.hashnode.com/uploads/covers/6950d1ca85602739c40abd67/0bfb2d33-c56f-4e7a-933b-12c20a99491b.png align="center")
