Async-Await vs. Then to Avoid Callback Hell 📞😈 
Tags: javascript, promises, beginners, tutorial
Published: 2019-04-19 06:24:45

---
title: Async-Await vs. Then to Avoid Callback Hell 📞😈 
published: true
description: 
tags: JavaScript, promises, beginners, tutorial
---

![Dante's Inferno Callback Hell](https://thepracticaldev.s3.amazonaws.com/i/5ofrscwnfljka6uhoe7j.jpg)

## Callback Hell 🔥

When working with JavaScript, there is a concept known as callback hell. It describes a deeply nested set of callback functions that is hard to read and maintain. Callback hell happens due to the asynchronous non-blocking nature of JavaScript. Below is an illustration based on Dante's 😈 nine circles of hell.

```js
hell() {
    firstCircle() {
        secondCircle() {
            thirdCircle() {
                fourthCircle() {
                    fifthCircle() {
                        sixthCircle() {
                            seventhCircle() {
                                eighthCircle() {
                                    ninthCircle() {
                                        alert("Hell has Frozen Over!")
                                    }
                                }
                            }
                        }    
                    }
                }
            }
        }
    }
}
```

## Promises

You commonly encounter callback hell when making an AJAX HTTP request. To flatten out nested callbacks for readability and maintainability, [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) can be used. With Promises, there are two techniques for flattening out our callbacks -- (1) [`then`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) and (2) [`async-await`](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await).

### `then`

This pattern helps flatten out nested callbacks into sequential `thens`. The entire execution of this `fetch` request is completely asynchronous and non-blocking.

```js
someFunc() {
    fetch('https://someurl.com')
        .then((response) => response.json())
        .then((data) => console.log(data)

    console.log("I will not be blocked")
}
```

### `async-await`

This pattern does the same thing, but is different because each line with `await` causes the code execution to block while waiting for the promise to [resolve](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve).

```js
async someFunc() {
    let response = await fetch('https://someurl.com'),
           data = await response.json()
    console.log("I will be blocked until I get a response", data)
}
```

## `async-await` vs `then`

### `async-await`

Useful to use if your code works with `Promises` and needs to execute sequentially. Due to blocking, you might lose some ability to process code in parallel. I've primarily used `async-await` when making API requests from a Node.js server.

### `then`

This has been most useful for me when working on the client so the UI thread is not blocked since requests are being processed in parallel. If you develop your frontend with React.js, a typical use case might be to display a loading screen until a `fetch` request returns and then using a `setState` to update the UI.

## Conclusion

Both `Promise` mechanisms can be used to solve the callback hell issue, each with their own optimal use cases. Don't limit yourself to any dogma. Do what makes sense for your use case.

> If you found this content useful and would like to get updates on new content, follow me on Twitter [@itspanw](https://twitter.com/itspanw).