Async Await vs Promises Example: Learn with Snippets

Async Await vs Promises
July 8, 2025
July 8, 2025

JavaScript is designed to handle asynchronous operations like API requests, file I/O, and timers without blocking the main thread. To manage these operations, developers commonly use Promises or async/await — two different ways to write asynchronous code.

In this guide, you’ll learn what each approach does, how they differ, and when to use one over the other, complete with real examples.

What Are JavaScript Promises?

A Promise is a built-in JavaScript object that represents a value that may be available now, later, or never. It provides a cleaner alternative to callback functions and supports chaining with .then() and error handling with .catch().

Example:

fetch('/api/user')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Key Points:

  • Promises allow you to attach callbacks for success (.then) and failure (.catch)
  • Support chaining for sequential operations
  • Error propagation through chained .catch()

What Is Async/Await?

Async/await provides a cleaner, more readable syntax for working with promises. Introduced in ES2017 (ES8), it simplifies writing asynchronous code that looks and behaves more like synchronous code, improving readability and structure.

Example:

async function getUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
getUser();

Key Points:

  • The `async` keyword defines a function that automatically returns a promise.
  • await pauses execution until the promise resolves
  • Simplifies error handling using try…catch

Async Await vs Promises: Key Differences

Feature Promises Async/Await
Syntax .then().catch() chains try...catch block
Readability Nested and sometimes hard to follow Looks synchronous and easier to read
Error Handling .catch() at the end try...catch block
Debugging Can be harder with long chains Stack traces are cleaner
Learning Curve Familiar to most devs Slightly easier for newcomers

Real-World Code Comparison

Using Promises:

function fetchData() {
return fetch('/api/data')
.then(res => res.json())
.then(json => {
console.log('Data:', json);
})
.catch(err => {
console.error('Error:', err);
});
}

Using Async/Await:

async function fetchData() {
try {
const res = await fetch('/api/data');
const json = await res.json();
console.log('Data:', json);
} catch (err) {
console.error('Error:', err);
}
}

Takeaway: Async/await improves readability, especially for complex flows.

When to Use Promises or Async/Await

Use Case Best Option
Multiple chained operations Promises
Simple linear flow Async/Await
Complex loops or conditional logic Async/Await
Executing operations in parallel Promises + Promise.all()
Legacy or existing promise-based code Promises

Common Pitfalls to Avoid

  • Forgetting to await an async call
  • Using both .then() and await within the same function.
  • Using await outside of async functions
  • Failing to wrap `await` calls in a `try…catch` block for proper error handling.

Conclusion

Async/await and promises both help you manage asynchronous code in JavaScript, but they serve slightly different needs.

If you’re working with complex logic that benefits from clearer structure and readability, async/await is often your best bet. For chaining or executing multiple tasks in parallel, promises (especially with Promise.all) still shine.

Choose the tool that best fits your use case — and feel free to combine both when needed.

FAQs

Q1: Is async/await better than promises?

A: It depends on your project needs and code structure.
Async/await is not a replacement for promises—it’s syntactic sugar built on top of them. It simplifies the code, making it look synchronous and easier to follow, especially for sequential operations or when you’re working with try/catch blocks for error handling. On the other hand, promises can be better suited for chaining multiple asynchronous operations or running tasks in parallel using .then() and Promise.all(). Both are equally powerful tools—choose based on what improves clarity and performance in your specific use case.

Q2: Are async functions still using promises under the hood?

A: Yes, absolutely.
When you define a function with the async keyword, it implicitly returns a promise. Even if you return a simple value inside the async function, JavaScript wraps it in a resolved promise. If an error is thrown inside the function, it results in a rejected promise. This allows async functions to integrate seamlessly with existing promise-based code.

async function getNumber() {
return 42;
}
getNumber().then(console.log); // Logs: 42

Looking for an Expert Web Designer and Developer for your business

Q3: Can I use Promise.all() with async/await?

A: Definitely—and it’s a great practice for running tasks concurrently.
You can use Promise.all() inside an async function and await its result to execute multiple asynchronous operations in parallel, which is much more efficient than awaiting each task one after the other.

async function loadData() {
const [user, posts, comments] = await Promise.all([
fetch('/api/user'),
fetch('/api/posts'),
fetch('/api/comments'),
]);
// Continue processing after all requests resolve
}

This ensures all requests are fired simultaneously, saving time and improving performance.

Related Posts