Mordern Javascript: Utilizing The Async-Await Feature.
Tags: javascript, node, api, programming
Published: 2022-08-06 07:56:00

## Introduction
In modern JavaScript where we have features like Promises and arrow functions etc. None of them are, In my opinion a bigger improvement to the language than Async-Await. Async-Await makes it easy to work with our promise based code that looks more synchronous than asynchronous.

In this article we would be looking at how Async functions work in great detail, It's advantages and practical use cases.

## What is Async-Await?
Async Await is merely a small set of tools that makes it easier to work with promises. It allows continuous usage of promise methods, and it helps us to better manage a lot of asynchronous activities while building our applications.


### Prerequisites 

- How to use the Command Line/Terminal.

- Basic Understanding of Javascript Promises. 

- Writing Arrow Functions.

- Using setTimeout(). 

- Node is installed.

### Getting Started
We'll start by creating a directory that contains our JavaScript file. You can go to your terminal and type the following:

```javascript
mkdir async
```

To change directory into `async` , type the code below:

```javascript
cd async
```
To create a new Javascript file called "async-await.js" with a variable inside it, type the code below:

```javascript
echo var msg > async-await.js
```
Now, we can open up our directory in visual studio code via the command below:

```javascript
code . 
```
## Functions and Async Functions (How they differ)
  
To really grasp how functions differ from Async Functions, Let us create an arrow function called 'doWork'. This function is going to be empty and we would log it's result to the console using the code below:

```javascript
let doWork = () => {
};
console.log(doWork())
```
This would print out on our terminal **undefined** when we run our async-await.js file, this is because functions usually expect a return value. To run our file, open up your command line and type:

```javascript
node async-await
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4cot2kmcflnh4qmg29x.png)
In order to make our function an async function, all we would do is mark the function as async, just before the function declaration. i.e 

```javascript
let doWork = async () => {
};
console.log(doWork())
```
With this small change to the code we are already changing the behavior of our program. We would no longer see **undefined** printing to our terminal. To see this, we need to run our file once again by using:

```javascript 
node async-await
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u33xl9bwfhhfy5rrobj8.png)
In this case what we get back is a promise that has been fulfilled with the value of **undefined**.

This is the first thing to note about async-functions, Async functions always return a promise. This promise is fulfilled with the value, you choose to return from the function. Currently we are not returning anything, that's why it is fulfilled with undefined.

Now, let us explicitly return a value from the async function. To do this, let us return a string containing my name.

```javascript
let doWork = async () => {
   return "Emmanuel"
};
console.log(doWork())
```
One thing to note though, the return value from `doWork()` is not "Emmanuel", it is actually still a Promise, that has been fulfilled with the string "Emmanuel". When we run our code, we see what this means


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7h8awflxh8pky596o5cr.png)


## Using `.then()` and `.catch()`

We aren't really doing much by just logging out a return value, let's see how to use the .then() method to run some code when the async function gets fulfilled.

To get this done, we just need to use the .then() method on our doWork function. As an example, we would simply log the result of its embedded arrow function. Which contains the return value of the async function

```javascript
let doWork = async () => {
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
})
```
Here's the `result` for that:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/as50nfxsupfhh20nvoc1.png)

We can also set up a .catch() call which is simply a function that gets an error. Lets's chain it to our .then() method with the code below:

```javascript
let doWork = async () => {
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
```
Just one small problem, When we run our file, we still get the result to be "Emmanuel".

So, how do we ever get .catch() to run?
Well, if we throw an error from our async function, It's going to be the same as rejecting the promise that gets sent back from the async function.
To throw an error, modify your code with the one below:

```javascript
let doWork = async () => {
   throw New Error("Something went wrong")
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
```
This time around, when we run our code we get our "e" string as well as the entire error object.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nenohtgb1bdu5yg794z6.png)

## Using the Await operator
So far we have looked at the basic structure of Asynchronous Functions. Now, we would be exploring the other half of the Async-<u>Await</u> feature.
The `await` operator can only be used in async functions and since the whole point of async await is to make things easier when working with promise based code. 

To spice things up, let's create a promise based code, this would just be a promise that adds up two numbers after two seconds, Here's the code for that:

```javascript
const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 2000)
    })
}

let doWork = async () => {
   throw New Error("Something went wrong")
   return "Emmanuel"
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})

```
If we were to use promise chaining, the code would require .then() calls and callback functions, just to get the value of add(). 

With Async-Await, it eliminates this monotonous way of doing things.

What we get access to, inside our async-funtion is the await operator. The await operator works with promises. And since we already have a promise called `add`, we would use it with the await operator. We are going to add two numbers together and then await the result of the add promise, which we would store inside our variable called "sum" and then return the value of "sum"

```javascript
const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 2000)
    })
}

let doWork = async () => {
   const sum = await add(1, 99);
   return sum
};

doWork().then((result) => {
   console.log("Result", result)
}).catch((e) => {
  console.log("e", e);
})
```
When we run our `async-await.js` file again, we get the result below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1aejopu79bvj5qhhnxg.png)

## Performing Multiple Tasks with Async-Await
Awesome, we have used await for the first time in our application. We can even take things a step further by performing other promise based tasks in our async function.

I would be making more calls to add() by using the value for the the previous sums. Here's the code for that
 

```javascript
const doWork = async () => {
   const sum =  await add(1, 99)
   const sum2 = await add(sum, 50)
   const sum3 = await add(sum2, 3)
   return sum3
}
```
This is going to make several calls to sum, we would have to wait 2 seconds for every promise to get fulfilled. This tells us that async-await doesn't necessarily make things faster, it just makes things easier to work with. After we wait for 6 seconds, we would get out final result to be *153*


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axipjs0baoowdttoem58.png)

One advantage Async-Await gives us, is the ability to put all of our promise calls in the same scope. This makes for more readable and synchronous looking code.

Now, all that's left is to wrap things up by writing some error handling code when our promises get rejected. We would be adding an if statement that helps us to check if the numbers to be added by sum() are negative numbers. We would return the reject code so that it finishes and then rejects the promise if that condition is met.

Let's improve our add() function by adding the if statement.

```javascript
const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (a < 0 || b < 0) {
                return reject('Numbers must be non-negative')
            }

            resolve(a + b)
        }, 2000)
    })
}
```

If we run our `async-await` file after this is added, we would get the same output, But when we make some changes to the numbers in add(), We get our error showing up: Here's the code and image for that below:

```javascript
const add = (a, b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (a < 0 || b < 0) {
                return reject('Numbers must be non-negative')
            }

            resolve(a + b)
        }, 2000)
    })
}

const doWork = async () => {
    const sum = await add(1, -99)
    const sum2 = await add(sum, 50)
    const sum3 = await add(sum2, -3)
    return sum3
}

doWork().then((result) => {
    console.log('result', result)
}).catch((e) => {
    console.log('e', e)
})
```
The output:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4yzfdbp4t846oem0zpd.png)
The output is going to get logged after we wait for the initial 2 seconds which is on our setTimeout() function.

### Conclusion
So far, we have looked at how async await differs from functions, the await operator and how to perform multiple tasks with async-await. We also learned that async-await gives us one-scope to put in our promises in.

I hope this article has been of help, Please leave a comment and follow me to get more content.