Premium Javascript Course

JavaScript Async/Await

JavaScript Async/Await is a modern way of working with asynchronous code. It simplifies the process of handling promises and makes asynchronous code look and behave like synchronous code. In this lesson, we will explore how to use async/await to handle promises and asynchronous operations in a more readable and maintainable way.

1. What is Async/Await?

Async and await are two keywords in JavaScript that allow us to work with promises in a cleaner and more readable way. The async keyword is used to declare an asynchronous function, while the await keyword is used to pause the execution of an async function until a promise is resolved or rejected.

2. Async Functions

An async function is a function that always returns a promise. Even if you return a non-promise value from an async function, it will be wrapped in a promise. You can use await inside an async function to wait for a promise to resolve before continuing execution.

Basic Syntax of Async Function:


async function myFunction() {
    return "Hello, world!";
}

myFunction().then(result => console.log(result)); // "Hello, world!"
        

In the example above, the function myFunction is declared as async. It returns a promise that resolves to the string "Hello, world!".

3. Using Await

The await keyword can only be used inside an async function. It pauses the function's execution until the promise is resolved or rejected. The value that the promise resolves to is returned by the await expression.

Example of Using Await:


async function fetchData() {
    let result = await fetch("https://api.example.com/data");
    let data = await result.json();
    console.log(data);
}

fetchData();
        

In this example, await pauses the function execution until the fetch request resolves, and then we extract the JSON data from the response.

4. Error Handling with Async/Await

Just like promises, async/await also allows for error handling. To handle errors in an async function, you can use a try...catch block. If the promise is rejected, the control will move to the catch block, where you can handle the error.

Example of Error Handling:


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

fetchData();
        

If the fetch request fails (e.g., due to network issues), the error will be caught in the catch block and logged to the console.

5. Combining Async/Await with Other Promises

You can use async/await along with other promises to handle multiple asynchronous operations. However, keep in mind that each await expression pauses the execution of the async function until the promise resolves. To run multiple async operations concurrently, use Promise.all() or Promise.race() with async functions.

Example of Using Async/Await with Promise.all:


async function fetchMultipleData() {
    let promise1 = fetch("https://api.example.com/data1");
    let promise2 = fetch("https://api.example.com/data2");
    let promise3 = fetch("https://api.example.com/data3");

    let results = await Promise.all([promise1, promise2, promise3]);

    let data1 = await results[0].json();
    let data2 = await results[1].json();
    let data3 = await results[2].json();

    console.log(data1, data2, data3);
}

fetchMultipleData();
        

In this example, Promise.all() is used to initiate multiple fetch requests concurrently. We then wait for all the promises to resolve using await and handle the results accordingly.

6. Async/Await with Loops

You can also use await inside loops, but it's important to note that await inside loops will make them run sequentially, not concurrently. To run tasks concurrently, use Promise.all().

Example of Async/Await with a Loop:


async function processItems() {
    let items = [1, 2, 3, 4, 5];

    for (let item of items) {
        let result = await fetch(`https://api.example.com/items/${item}`);
        let data = await result.json();
        console.log(data);
    }
}

processItems();
        

In this case, each request waits for the previous one to finish. If you need them to run concurrently, you should use Promise.all() or similar approaches.

7. Conclusion

Async/Await simplifies the handling of asynchronous operations and provides a cleaner, more readable way to write asynchronous code. By using async functions and await expressions, you can avoid callback hell and promise chaining, making your code easier to understand and maintain. Combine async/await with other promise handling techniques like Promise.all() for concurrent tasks, and use try...catch for robust error handling in your asynchronous workflows.