async/await
JavaScript
promise rejection
asynchronous programming
error handling

How to reject in async/await syntax?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction to Async/Await

Asynchronous programming is a powerful feature in modern JavaScript that enables developers to write non-blocking code. The introduction of the async and await syntax in ECMAScript 2017 provides a cleaner and more readable way to deal with promises compared to traditional .then() and .catch() methods. This article focuses on how to reject promises using async and await.

Understanding Async/Await

Before diving into rejecting promises, let's quickly recap how async and await work:

  • Async Functions: Declaring a function with the async keyword automatically returns a promise. Within this function, you can use the await keyword to pause the execution until the promise is settled.
  • Await Expressions: await can only be used inside an async function. It pauses the execution of the async function and waits for the promise to resolve or reject.

Rejecting Promises with Async/Await

In the context of async/await, rejecting promises can be handled using throw statements. When a promise is rejected inside an async function, it should be done using the throw keyword. This can be caught by a try-catch block surrounding the await expression.

Example of Rejection

javascript
1async function fetchData(url) {
2    if (!url) {
3        throw new Error('URL is required');
4    }
5
6    return await fetch(url)
7        .then(response => response.json())
8        .catch(error => {
9            throw new Error('Failed to fetch data');
10        });
11}
12
13(async () => {
14    try {
15        const data = await fetchData('https://example.com/data');
16        console.log(data);
17    } catch (error) {
18        console.error('Error:', error.message);
19    }
20})();

Explanation

  • In fetchData, we check if the url is provided. If not, we immediately throw an error.
  • If fetch fails for any reason, it’s caught and a new error is thrown.
  • The calling context makes use of a try-catch block to handle the rejection.

Handling Rejections

Handling promise rejections using async/await involves wrapping await expressions in a try-catch block. This allows for a more synchronous-like handling of asynchronous operations.

Example

javascript
1async function performOperation() {
2    try {
3        let result = await someAsyncFunction();
4        console.log('Operation succeeded:', result);
5    } catch (err) {
6        console.log('Operation failed:', err.message);
7    }
8}

Explanation

  • The try block includes the await operation, potentially throwing an exception.
  • The catch block will catch any errors thrown by await or within the async function, thus preventing unhandled promise rejections.

Comparing Traditional Promises and Async/Await

Traditional Promise Rejection

javascript
1someAsyncFunction()
2    .then(result => {
3        // fulfilled
4    })
5    .catch(error => {
6        // rejected
7        console.log('Error:', error);
8    });

In this traditional pattern, error handling is explicitly defined using .catch().

Table: Key Differences between Traditional Promises and Async/Await

AspectTraditional PromisesAsync/Await
Syntax ComplexityChaining .then() and .catch()Cleaner with simple try-catch blocks
ReadabilityCan become messy with multiple operationsSynchronous-like and easy to read
Error HandlingMust handle each promise with .catch()Use a single try-catch for multiple awaits
Sequential OperationsRequires chaining and nestingMore straightforward with await

Conclusion

The async/await syntax simplifies asynchronous programming in JavaScript by making the code more readable and easier to maintain. Understanding how to handle promise rejection is crucial in building reliable applications. By using try-catch blocks effectively, developers can ensure their code gracefully handles errors and remains performant.

Whether using traditional promise chains or the modern async/await syntax, proper rejection handling is pivotal. As you build applications, remember that clean error handling leads to robust and user-friendly software.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.