🚀 Demystifying Async/Await as Generators + Promises
Tags: javascript, webdev, uiweekly, generators
Published: 2021-02-07 00:00:45

> 
- Async/Await solves the problem of Inversion of Control with callbacks.
- Generators build-up to Async/Await

| Contents |
|-|
| [Introduction](#introduction) |
| [Async/Await](#async-await) |
| [Generators](#generators) |
| [Async/Await through generators](#async-generators) |

___
___

### Introduction <a name="introduction"></a>
JavaScript being single-threaded, should not be blocked for long-running tasks.
Callbacks are the answer to execute such tasks without blocking the main thread. However, they cause __Inversion of Control__. _The invocation of callbacks is passed to a function over which you do not have control_.

Async/Await solves that problem. In this article, we would compare the same example and break down the similar working of the async/await function with the help of generators.

___

### Async/Await <a name="async-await"></a>

Async functions help us write asynchronous code (Promises) in a more synchronous manner.

Things to note about async functions - 
1. Async functions always return a Promise, returned values are enclosed in a promise if they are not thenables.
2. Await keyword can only be used within an async function, it is used to await the value of a promise.

![async await example](https://dev-to-uploads.s3.amazonaws.com/i/1fs0iv0xs534yb3ijn77.png)

In the above snippet, the invocation of the async function returns us the data, without having to do a .then over the two promises returned from the fetch API and its parsing process.

___

### Generators <a name="generators"></a>

Generators are functions that do not run to completion. They can be paused and resumed. Until the function is completed, its context is preserved. It returns a generator object which has the information about the function context. It can be inspected by logging an execution of a simple generator function. This helps us write asynchronous code in a somewhat synchronous manner.

![generator example](https://dev-to-uploads.s3.amazonaws.com/i/m9msjztir2rmmqt3l70a.png)

1. The generator object is compatible with the Iterable protocol, thus a .next() can be invoked to get subsequent values i.e. control goes back within the generator function.
2. Values are exchanged between the generator function and outer code via next/yield. 

![Iterator interface](https://dev-to-uploads.s3.amazonaws.com/i/eoo7u60zohpsgw2s3yum.png)
 
___

###Async/Await through generators <a name="async-generators"></a>

Understanding the generators is essential for the last part of the article. It is where Promises and Generators will be composed to create our own async/await implementation.

![almost there](https://media.giphy.com/media/VFHWGT96hbfsjDJ57S/giphy.gif)

The above code snippet is analogous to the async/await code snippet at the top. Here is the breakdown of the steps -
1. A generator function is required for it, yield is analogous to the await keyword.
2. The asyncify function returns a Promise, which embodies the await logic.
3. The manual invocation of the iterator.next() method which was seen in the generator's example is done within the promise body.
4. The logic would be recursively invoked until the IteratorResult has 'done' as true 

![asyncify](https://dev-to-uploads.s3.amazonaws.com/i/ns1r22fjpc1yn2hmixar.png)
 
Ultimately, the `asyncified` function would be consumed in a similar manner as an async function is. As it returns a Promise, it should be consumed via a success and error handler.

![asyncified consumption](https://dev-to-uploads.s3.amazonaws.com/i/zhgabsie3dq65jjftnd0.png)

---
All above snippets can be run [here](https://codepen.io/sagarrth/pen/PobNpwZ)
Reference: [ExploringJS](https://exploringjs.com/es6/ch_generators.html)

That's all people!