What is async/await in JavaScript?

JavaScript

readTime

4 min

What is async/await in JavaScript?

If you’re just starting out with programming, especially in JavaScript, you’ve probably come across terms like "asynchronous" or "Promises."

When coding in JavaScript, many operations are asynchronous—especially those involving internet requests, like fetching data from an API.

This is where async/await comes into play: two keywords introduced in ECMAScript that revolutionized the way we write asynchronous code.

With async and await, writing code to manage asynchronous operations becomes much cleaner and easier to maintain.


What is async/await?

Async/await is a way to write asynchronous code in a synchronous style.

This means the code is still asynchronous but visually feels like regular synchronous code, executed line by line.

Instead of using callbacks or Promises with .then() chaining, you can mark a function as async and use await to "pause" execution until an asynchronous operation finishes.


The History and Evolution of async/await

Async/await was added to JavaScript in 2017 as part of ECMAScript 2017 (ES8).

It was introduced to address the complexities of earlier methods for handling asynchronicity, such as callbacks and Promises.

  • Callbacks led to the infamous "callback hell," where deeply nested calls became hard to manage.
  • Promises improved the situation by allowing chaining with .then(), but they were still not as intuitive as synchronous code.

Async/await finally enabled developers to write more readable and intuitive code for handling asynchronous tasks.


Comparison with Other Asynchronous Methods

Callbacks

Callbacks were the first method for handling asynchronicity in JavaScript. The problem arose when multiple asynchronous operations needed to be chained together, resulting in hard-to-read, nested code.

Promises

Promises were a significant improvement, enabling .then() chaining to reduce nesting. However, they still required a structured approach to avoid excessive chaining and .catch() handling.

Async/await

With async/await, you can use Promises in a syntax that feels like synchronous code. This eliminates nesting and makes your code much clearer.


How does async/await work in JavaScript?

  • A function marked with the async keyword always returns a Promise.
  • The await keyword can only be used inside an async function and pauses execution until the Promise resolves or rejects.

Example:

javascript
async function downloadData() {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();
  return data;
}

Here, the downloadData function uses await to wait for the API response. The code looks synchronous but executes asynchronously.


Why use async/await?

  1. Readability: Code written with async/await is much easier to read and understand, especially for beginners.
  2. Error Handling: Instead of using .catch() on Promises, you can use try/catch blocks inside async functions, which is more intuitive.

Promises as the Foundation of async/await

To understand async/await, you first need to understand Promises. Async/await is just a cleaner syntax for working with Promises.


What is a Promise?

A Promise is an object that represents an asynchronous operation and "promises" to complete in the future.

It can either:

  • Resolve (success),
  • Reject (failure).

Example of a Promise:

javascript
let myPromise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Success!"), 1000);
});

myPromise.then((result) => {
  console.log(result); // Outputs: "Success!"
});

States of Promises:

  • Pending: The operation is ongoing.
  • Fulfilled: The operation completed successfully.
  • Rejected: The operation failed.

Writing Async/Await

Using async

Marking a function as async means it always returns a Promise.

Example:

javascript
async function fetchData() {
  return "Result";
}

Using await

Await pauses the execution of an async function until a Promise resolves.

Example:

javascript
async function getData() {
  const response = await fetch("https://api.example.com");
  const data = await response.json();
  return data;
}

Error Handling with try/catch

Async/await allows you to handle errors using try/catch blocks.

Example:

javascript
async function fetchData() {
  try {
    const response = await fetch("https://api.example.com");
    const data = await response.json();
    return data;
  } catch (error) {
    console.log("Error:", error);
  }
}

Real-World Use Cases of async/await

  1. Fetching Data from an API Async/await is ideal for fetching data in a clean and readable way.

    javascript
    async function fetchData() {
      const response = await fetch("https://api.example.com/data");
      return response.json();
    }
    
  2. Processing Data When dealing with file or data processing, async/await helps manage operations efficiently.

    javascript
    async function processFile(file) {
      const content = await file.read();
      console.log(content);
    }
    
  3. Database Queries For applications using databases like MongoDB or MySQL, async/await simplifies query management.

    javascript
    async function getUser(id) {
      const user = await db.query(`SELECT * FROM users WHERE id = ${id}`);
      return user;
    }
    

Best Practices with async/await

  1. Avoid Nesting: Keep your async/await logic flat to maintain readability.
  2. Use Promise.all for Parallel Tasks:
    javascript
    const [data1, data2] = await Promise.all([
      fetch("https://api.example.com/data1"),
      fetch("https://api.example.com/data2"),
    ]);
    
  3. Always Handle Errors: Use try/catch or .catch() to manage exceptions.

Summary

Async/await revolutionized asynchronous programming in JavaScript, making it easier to read, maintain, and debug.

Use it wherever you need to handle asynchronous operations like API calls, file processing, or database queries. By following best practices, async/await will make your JavaScript code cleaner and more robust. 🚀

authorImg

Witek Pruchnicki

I passionately share knowledge about programming and more in various ways.