Simpler Asynchronous JavaScript code with Async/await
Tags: javascript, async, promises, todayilearned
Published: 2020-11-30 15:34:54

It all started when our class began learning about Promises. In short, a promise is an object that represents awaiting for some operation to complete. There are situations where you might need promises and situations where you will not. For example, if you are looking things up in the DOM or writing to the DOM, this code executes _synchronously_, meaning our code will block and wait for the result on that particular line.
In the following example, we are doing a simple query for an `<h2>` element in our document:
```javascript
let lookUp = document.querySelector("h2")
```
JavaScript, while it is executing this line, will not be doing anything else. The result will be returned to `lookUp` before executing the next line. So there are some (most) operations in JS where it will automatically _wait_ for a result.

For other things, such as HTTP requests, JS will *not* wait for a result, therefore promises are needed to allow JS to continue executing other operations while waiting for results. The following example will only start the operation but will not give us the final result yet. 
```javascript
let promise = fetch("http://example.com")
```
Async functions help us with the situations where JS will *not* automatically wait for a result.

For a more complete understanding of promises, as well as this blog post, you can read up on promises [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

I happened to have stumbled upon async functions. Every time I wrote a fetch request inside a function using `.then` syntax,  I would get these faint-colored dots right below the function's name. Upon clicking on these dots, VSCode gives you the option to convert it to an async function, as demonstrated below:

![gif shows async function](https://s8.gifyu.com/images/CleanShot-2020-11-27-at-11.16.44.gif)

I have since started using async functions for any HTTP request, but without knowing much of its functionality. I decided to write this blog post as I became curious about the different syntax and if there are benefits to writing async functions. This blog post is a beginner's level explanation of how async functions work. A decent amount of research was done, but as a beginner to JavaScript myself, please feel free to leave any feedback, and I will gladly update this post.


Before we get into the syntax of `async/await`, we should review what a regular function that will handle asynchronous operation will look like. 
The following snippet shows a fetch request using `.then` syntax:

```javascript
function sameFunction() {
  return fetch("some_url")
    .then((response) => response.json())
    .then((resultFromResponse) => doSomethingWithResult(resultFromResponse));
}
```
When using a regular function or non-async function, the code can look somewhat messy and more difficult to understand. Also normal built-in JavaScript syntax such as `if` statements and `for` loops become difficult to use.

#### Async Functions

But what is an `async` function? This is what I've gathered so far:

- These are regular functions that will begin with the keyword `async`.
- Once marked with `async`, the function will only return promises now.
- Once marked with `async`, the `await` keyword can be used _inside_ the function to help with handling promises.

In one snippet, 
```javascript
async function someName() {
  let response = await fetch("some_url");
  return await response.json();
}
someName() // => Promise<pending>
```

Async functions with the await keyword make for _much_ simpler handling of promises. The await keyword does exactly what you might think it would, it waits until a promise is either fulfilled or rejected to resume. Meanwhile, other functions in your code will be allowed to run. Keep in mind that the `await` keyword only works inside `async` functions.

Just a heads up, `async` functions are not currently supported by all browsers, and you might have to use some [other tools](https://babeljs.io/) to make it more widely compatible. 

####Error handling

The last thing I would like to address is error handling. In regular functions, when handling errors, you need to consider errors that can happen asynchronously. Consider the following example:

```javascript
function errorHandlingDemoWrong() {
  try {
    fetch("http://thisisjustademo.com/").then((res) => {
      console.log(`status code: ${res.status}`);
    });
  } catch(e) {
    console.log("this will never happen")
  }
}
```

This function is trying to fetch this domain and because the domain does not exist, it will error out. Because the error occurred inside the promise chain, it will stay within the promise chain. Therefore `catch` in this snippet will never be executed.
 
The correct way to handle this error would be to use `.catch`:

```javascript
function errorHandlingDemoCorrect() {
  fetch("http://thisisjustademo.com/")
    .then((res) => {
      console.log(`status code: ${res.status}`);
    })
    .catch((err) => {
      console.log(`an error occurred while fetching fake domain: ${err}`);
    });
}
```

As a beginner, trying to figure out which is the right way to handle errors can be confusing. 

This is another way `async/await` makes writing JavaScript better. In this snippet, **all** error handling is done with the built-in `try/catch` syntax, instead of there being two different error handling methods.

```javascript
async function errorHandlingDemo() {
  try {
    let response = await fetch("http://thisisjustademo.com/");
    console.log(`status code: ${response.status}`);
  } catch (err) {
    console.log(`an error occurred while fetching fake domain: ${err}`);
  }
}
```

Handling asynchronous code can be very tricky, and `async/await` makes it easier and more readable.