Async/Await — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle
Tags: javascript, node, webdev, programming
Published: 2023-05-08 09:28:30

---
title: Async/Await — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle
published: true
description: Make your asynchronous code more readable and easier to understand.
tags: javascript, node, webdev, programming
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-05-08 09:24 +0000
---

![Async/Await](https://cdn-images-1.medium.com/max/2000/1*1AbFNfBpOPerfVszgsWgoA.png)

Before this article, I mentioned to you that I would start the articles series and I already created an Introduction, V8 JavaScript engine, Callbacks, AJAX and XMLHttpRequest, Synchronous and Asynchronous, and about the Promises. If you lost what I did, check it:

* [Introduction — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/introduction-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-2f08)

* [V8 JavaScript engine — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/v8-javascript-engine-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-1m6j)

* [Callbacks — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/callbacks-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-41b9)

* [AJAX and XMLHttpRequest — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/ajax-and-xmlhttprequest-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-4ap6)

* [Synchronous and Asynchronous — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/synchronous-and-asynchronous-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-22b3)

* [Promises — Understanding JavaScript API Requests and Responses in the Data Fetching lifecycle](https://dev.to/rodcast/promises-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-2imo)

*In this article, I’ll not explain the concept of Fetch API but don’t worry that I’ll explain it in the next article.*

The [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) and [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) is a way to write asynchronous JavaScript code that is more readable and easier to reason about, and it provides a more straightforward and less error-prone way of dealing with promises than traditional promise chains.

The *async* keyword is used to define a function that returns a promise. This allows you to use the *await* keyword inside the function to wait for asynchronous operations to complete.

The *await* keyword can only be used inside a function marked as *async* ([async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)). When you use *await* outside of an async function, you’ll get a syntax error.

There are some ways to declare (define) JavaScript functions using *async*:

```javascript
    // function declaration
    async function foo() {
      return "Lorem";
    }
    
    // function expression
    const = async function foo() {
      return "Lorem";
    }
    
    // arrow function
    const foo = async () => {
      return "Lorem";
    };
    
    // arrow function (shorthand)
    const foo = async () => "Lorem";
    
    // Immediately Invoked Function Expression (IIFE) 
    (async () => {
      return "Lorem";
    })();
```

Following *async/await* can make your code more readable in many cases. By using async/await, you can write asynchronous code that looks more like synchronous code, which can make it easier to understand and follow the logic of your code, without having to use complex and confusing callbacks or promises.

### async/await and Fetch API

Together, *async/await* and the *Fetch API* both provide a powerful, efficient, and easy understand.

*Async/await* works by allowing developers to define functions as *async* and then use the *await* keyword to wait for the result of a promise to resolve.

*Fetch API* is designed to work with asynchronous operations, which allows making requests to an API or server without blocking the main thread of the application and always *fetch()* method returns a Promise.

By default, the *fetch()* method uses the GET method, then all the examples will use it.

Obviously, you can use Promises with the *.then()* and *.catch()* methods to handle the asynchronous response from the API:

```javascript
    fetch("https://api.chucknorris.io/jokes/random")
      .then((response) => response.json())
      .then((data) => {
        // Request was successful
        console.log(data);
      })
      .catch((error) => {
        // If an error occurs, see the error in the console.
        console.error(error);
      });
```

But when you use *async/await* is often considered a cleaner and more readable approach because it avoids nested callbacks and provides a more linear and readable code flow. The *try/catch* block is used to handle any errors that may occur during the API request or parsing of the response, which is similar to the *.catch()* method in the first example. However, it provides a more elegant way to handle errors, as any errors that occur during the *try* block will be caught in the *catch* block.

***It is not obligatory to use async always in JavaScript, nor is it required to use try/catch in every situation. The choice between async and try/catch depends on the specific requirements and context of your code.***

```javascript
    try {
      const response = await fetch("https://api.chucknorris.io/jokes/random");
      const data = await response.json();
    
      // Request was successful
      console.log(data);
    } catch (error) {
      // If an error occurs, see the error in the console
      console.error(error);
    }
```

>  Of course, readability is subjective and depends on the context of your code. However, in general, async/await can make your asynchronous code more readable and easier to understand, especially when working with complex or nested asynchronous operations.

If you want to fetch multiple API requests in parallel, you can use [Promise combinators](https://medium.com/@rodcast/promises-understanding-javascript-api-requests-and-responses-in-the-data-fetching-lifecycle-178f1277cb88#4530).

In the example below, I’m using *Promise.all* method to GET the [JSONPlaceholder](https://jsonplaceholder.typicode.com/) which is a free API whenever you need some fake data for testing and prototyping:

```javascript
    // Create an array with 5 different todo url items.
    const todoList = Array.from({ length: 5 }).map(
      (_, number) => `https://jsonplaceholder.typicode.com/todos/${++number}`
    );
    
    // Fetch the 5 different todo items using Promise.all method and
    // return an array of responses and data.
    const fetchTodoList = async (urls) => {
      try {
        const responseList = await Promise.all(urls.map((url) => fetch(url)));
        const dataList = await Promise.all(
          responseList.map((response) => response.json())
        );
        console.log(dataList); // Output: array with 5 different todo object items.
      } catch (error) {
        console.error(error);
      }
    };
    
    // Create an array with 5 different todo object items.
    fetchTodoList(todoList);
```

There’s one another good example using the *async/await* to get the categories list and category detail now using the [Chuck Norris Jokes API](https://api.chucknorris.io/):

```javascript
    const getCategories = async () => {
      const response = await fetch("https://api.chucknorris.io/jokes/categories");
      const data = await response.json();
      return data;
    };
    
    const getCategory = async (category) => {
      const response = await fetch(
        `https://api.chucknorris.io/jokes/random?category=${category}`
      );
      const data = await response.json();
      return data;
    };
    
    const getCategoriesItems = async () => {
      const categories = await getCategories();
    
      for (const category of categories) {
        await getCategory(category);
      }
    };
```

>  In summary, if you're dealing with asynchronous operations, using async/await along with try/catch can provide a powerful error handling mechanism. However, if you're working with synchronous code or don't need to pause the execution of code, try/catch alone can handle errors effectively. The choice between async/await and try/catch depends on the nature of your code and the requirements of error handling.

>  The combination of async/await and the Fetch API simplifies the process of handling HTTP requests and responses. With Fetch API, developers don’t have to deal with complex XHR objects or callbacks. The syntax for making a fetch request is straightforward, and it’s easy to extract the data from the response object.

>  async/await can simplify asynchronous programming in JavaScript, but it can also introduce additional complexity and potential issues. Always you need to be mindful of these potential issues and have a solid understanding of asynchronous programming, error handling, state management, performance considerations, and debugging when using async/await.

So, If you want to know more about Fetch API, please wait for the next article that I’ll publish.

Thank you for reading, I hope this article can somehow have increased your knowledge base about it.