Three Ways to Make an Async Request in JavaScript: XHR, Promise, Async/Await
Tags: webdev, javascript, promise, tutorial
Published: 2023-03-11 22:10:37

Asynchronous programming is a crucial part of modern-day JavaScript development. It allows you to make requests to servers, access databases, and manipulate the DOM without blocking the main thread of execution.

The way we develop code in 2023 is very different from how it was done in the 2000s. We now have access to promises, async/await, and the fetch API, whereas back then we were using XHR and callbacks. If you were handed a legacy frontend project, this article can help you understand how it was done in the past so that you can rewrite it into a modern codebase if necessary.

In this article, we will build a simple program that fetches JSON from a URL and prints the result to the console. We will use code patterns from different eras of JavaScript. 

### The 2005 way: XMLHttpRequest (XHR)

XMLHttpRequest (XHR) is an API in the form of an object that is used to transfer data between the web browser and a server. It is the oldest way to make an asynchronous request in JavaScript. XHR provides a way to make HTTP requests to the server and get responses without having to reload the entire page.

Here is an example of how to make an XHR request:

```jsx
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', true);
xhr.onload = function () {
    if (this.status === 200) {
        console.log(JSON.parse(this.responseText));
    } else {
        console.error('Error');
    }
};
xhr.send();
```

Or maybe you were using jQuery? It was a popular JavaScript library that simplified HTML document traversing, event handling, animating, and Ajax interactions. This is what the same request will look like in jQuery:

```jsx
$.getJSON('https://jsonplaceholder.typicode.com/todos/1', function(data) {
  console.log(data);
});
```

### The 2015 way: Fetch and promises

**Fetch** is a newer and more modern technology that replaces XHR, or XMLHttpRequest. It is built directly into modern web browsers, which means that it is easier to use and requires less overhead than XHR. It uses **Promises** instead of callbacks, which makes it easier to manage asynchronous calls without getting bogged down in complex code.

**Promise** is an object in JavaScript that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It allows you to write asynchronous code that is more readable and maintainable by chaining together methods like `then()` and `catch()` to handle the result of a Promise.

Here is an example of how to make an async request using Fetch and Promises:

```jsx
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error(error));
```

### The 2023 way: Async/await

Async/await is a modern way of writing asynchronous code that is built on top of Promises. It allows you to write asynchronous code that looks like synchronous code. Here is an example of how to make an async request using Async/await:

```jsx
async function getData() {
  try {
    const response = await fetch('<https://example.com/api/data>');
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}
getData();
```

Note that we have to wrap the code in a `getData` function as `await` statement cannot be called in top level code.

## Conclusion

We explored three different ways to make asynchronous requests in JavaScript. When possible, avoid using legacy code and instead utilize new language features. However, make sure that the target browsers support these features. You can check [caniuse.com](http://caniuse.com/) if you're unsure.

Thank you for reading! I hope this article has been helpful to you. Happy coding!