Dev Tips & Tricks

Async / Await in JavaScript: How to Improve Your Code

Back to posts

JavaScript is often described as an asynchronous programming language because it provides features and tools for effectively handling asynchronous operations. In fact, JavaScript is a single-threaded language, but it uses event-driven and non-blocking mechanisms for handling asynchronous tasks.

When using asynchronous code in JavaScript, the program does not halt and wait for long-running operations to complete before continuing. Instead, the program can register a callback to execute when the operation completes and proceed to execute other code in the meantime.

The ability to remain responsive and efficient while waiting for lengthy operations is a valuable trait of asynchronous programming in JavaScript. However, writing asynchronous code can be challenging, less readable and more difficult to maintain.

Async/await is a syntax used for handling promises in JavaScript, introduced in ECMAScript 2017. It was designed to simplify writing asynchronous code in JavaScript and make it appear as synchronous code.

Here is a straightforward example of using async/await to make an asynchronous HTTP request:

async function getData() {
  try {
    // make the HTTP request
    const response = await fetch('https://my-json-server.typicode.com/typicode/demo/posts');
    
    // parse the response as JSON
    const data = await response.json();
    
    // return the data
    return data;
  } catch (err) {
    // handle any errors
    console.error(err);
  }
}

// call the function and log the result
getData().then(data => console.log(data));

A you can see, in this example, the 'getData()' function uses the 'await' keyword to wait for the 'fetch()' call to complete before parsing the response as JSON and returning the data.

Async/await streamlines working with promises because it enables you to use the 'try' and 'catch' keywords to handle errors, similar to how you would in synchronous code. This approach also makes the code look and feel like it is executing synchronously, enhancing the readability and comprehensibility of your code.

In JavaScript, a promise is an object that represents the outcome of an asynchronous operation. Promises offer an elegant way to handle asynchronous operations in JavaScript and are vital for working with asynchronous code.

Prior to promises, developers relied on callback functions to manage asynchronous operations, which sometimes led to "callback hell": a situation where code became deeply nested and challenging to maintain.

A promise can be in one of three states: pending, fulfilled, or rejected. When a promise is first created, it is in the pending state. Once the asynchronous operation completes, the promise will either be fulfilled with a value or rejected with an error. Here's an example:

// create a new promise
const myPromise = new Promise((resolve, reject) => {
  // make the HTTP request
  fetch('https://my-json-server.typicode.com/typicode/demo/posts')
    .then(response => response.json()) // parse the response as JSON
    .then(data => resolve(data)) // fulfill the promise with the data
    .catch(err => reject(err)); // reject the promise with an error
});

// use the promise
myPromise
  .then(data => console.log(data)) // handle a successful result
  .catch(err => console.error(err)); // handle an error

So, in the above example, we created a 'myPromise' object using the 'Promise' constructor and provided it with a callback function. Within this callback function, we initiated an HTTP request and, upon receiving the response, we parsed it as JSON. Depending on the outcome, the promise is either fulfilled with the data or rejected with an error.

Subsequently, the 'myPromise' object becomes accessible for handling the results of the asynchronous operation. This is achieved by invoking its 'then()' and 'catch()' methods. If the operation succeeds, the 'then()' method is triggered, allowing you to work with the data. In case of an error, the 'catch()' method handles the error gracefully.

Keep in mind that async/await is widely supported by modern web browsers, and you can use it in any JavaScript environment that supports promises, including Node.js. So, whether you are developing for the web or working in server-side JavaScript with Node.js, async/await can greatly improve your coding experience and help you build more responsive and efficient applications. Happy coding!

Share with
Terms of Use | Privacy Policy