DEV Community

Cover image for Mastering Async/Await in JavaScript Like a Pro!
Harish Kumar
Harish Kumar

Posted on

Mastering Async/Await in JavaScript Like a Pro!

1. Introduction to Async/Await

Async/Await is a much more modern JavaScript syntax for dealing with asynchronous operations of a program in a much smoother and more intuitive way. It was launched within ECMAScript 2017, or ES8, that eases working with Promises and gives asynchronous-looking and-behaving, synchronous-like code.

👉 Download eBook - JavaScript: from ES2015 to ES2023

.

Importance in Modern JavaScript Development

Asynchronous programming is definitely important in JavaScript, most particularly in tasks like API calls, file handling, and timers. Async/await also enhances readability and many other maintainability aspects of the code; hence, easier writing and debugging.

Basic Syntax

The async keyword applies the definition of an asynchronous function, while the await keyword is then applied to cause the function execution to actually pause until a promise has been resolved.

async function example() {
    let value = await someAsyncFunction();
    console.log(value);
}
Enter fullscreen mode Exit fullscreen mode

2. Understanding Asynchronous Programming

Synchronous vs. Asynchronous Operations

  • Synchronous: The operations are executed one after the other; each subsequent operation is blocked until the previous one is completed.
  • Asynchronous: The operations can run irrespective of the main program's flow; the program can continue with other tasks in its execution.

Callbacks and Promises as Predecessors

  • Callbacks: A function is passed as an argument to another function, which is executed once an asynchronous operation is complete. It can result in "callback hell."
  • Promises: It is an object that represents the eventual completion or failure of an operation. This approach makes the code more readable compared to callbacks, but sometimes it can also lead to complexity and mess.

3. Async Functions

Definition and Usage

An async function is a function declared using the async keyword. It enables you to write the Promise-based code as much simpler async/await syntax, and you can write async in it, which suspends the execution until a Promise resolves.

How to Declare an Async Function

async function fetchData() {
    let response = await fetch('https://api.example.com/data');
    let data = await response.json();
    return data;
}
Enter fullscreen mode Exit fullscreen mode

4. Await Keyword

Definition and Usage

The await keyword is used to wait for a Promise to resolve. It can only be used inside an async function.

How it Works within Async Functions

When await is encountered, the async function pauses execution until the Promise settles. The resolved value of the Promise is then returned.

async function getUser() {
    let user = await fetchUserFromDatabase();
    console.log(user);
}
Enter fullscreen mode Exit fullscreen mode

5. Error Handling

Using Try/Catch with Async/Await

Errors in async functions can be handled using try/catch blocks, similar to synchronous code.

async function fetchData() {
    try {
        let response = await fetch('https://api.example.com/data');
        let data = await response.json();
        return data;
    } catch (error) {
        console.error('Error fetching data:', error);
    }
}
Enter fullscreen mode Exit fullscreen mode

Common Pitfalls and How to Avoid Them

  • Forgetting to use await: Leads to unhandled Promises.
  • Using await outside of async functions: Causes syntax errors.

6. Practical Examples

Fetching Data from an API

async function getApiData() {
    let response = await fetch('https://api.example.com/data');
    let data = await response.json();
    console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

Sequential vs. Parallel Execution

  • Sequential Execution:
  async function sequentialTasks() {
      let result1 = await task1();
      let result2 = await task2();
      console.log(result1, result2);
  }
Enter fullscreen mode Exit fullscreen mode
  • Parallel Execution:
  async function parallelTasks() {
      let [result1, result2] = await Promise.all([task1(), task2()]);
      console.log(result1, result2);
  }
Enter fullscreen mode Exit fullscreen mode

7. Advanced Topics

Async/Await with ES6 Modules

Async functions can be exported and imported just like any other functions in ES6 modules.

// module.js
export async function fetchData() {
    let response = await fetch('https://api.example.com/data');
    return await response.json();
}

// main.js
import { fetchData } from './module.js';

fetchData().then(data => console.log(data));
Enter fullscreen mode Exit fullscreen mode

Combining with Other Asynchronous Patterns

You can combine async/await with other Promise methods like Promise.all for concurrent execution.

async function loadData() {
    let [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
    console.log(users, posts);
}
Enter fullscreen mode Exit fullscreen mode

8. Conclusion

Summary of Key Points

  • Async/await provides a more readable and maintainable way to handle asynchronous operations.
  • Async functions return Promises, and await pauses execution until the Promise resolves.
  • Error handling is straightforward with try/catch.
  • Practical use cases include API calls and concurrent task execution.

Best Practices

  • Always use await inside async functions.
  • Handle errors gracefully with try/catch.
  • Use Promise.all for parallel execution to improve performance.

👉 Download eBook
javascript-from-es2015-to-es2023

Top comments (0)