When people start learning asynchronous JavaScript, Promise and async/await appear almost immediately. The syntax can look approachable, but without understanding why these tools exist, the code becomes confusing again very quickly.
async/await makes asynchronous code look more sequential, which improves readability, but that does not mean the underlying behavior has suddenly turned into truly synchronous blocking execution.
This guide covers:
- what Promise is
- why
async/awaitexists - how both differ from callback-heavy code
The key idea is this: Promise represents a value that will complete later, and async/await is syntax that makes Promise-based async code easier for humans to read and maintain.
What is a Promise?
A Promise is a JavaScript object that represents work whose result does not exist yet but will exist later.
For example, a network request does not return data immediately. A Promise provides a standard way to describe whether that work is:
- still waiting
- completed successfully
- failed
and lets you attach follow-up logic for when the result arrives.
So a useful mental model is: Promise is a standard wrapper for future results.
Why were callbacks awkward?
Before Promise became common, asynchronous follow-up logic was often written with nested callbacks.
fetchUser(userId, function (user) {
fetchOrders(user.id, function (orders) {
saveLog(orders, function () {
console.log('done');
});
});
});
That can work in small examples, but as flows grow, nesting becomes harder to scan, error handling gets scattered, and the code becomes harder to restructure.
Promise did not solve every problem, but it made continuation flow much more structured.
How should you read Promise chains?
The classic Promise style uses .then(), .catch(), and sometimes .finally().
fetchUser(userId)
.then((user) => fetchOrders(user.id))
.then((orders) => saveLog(orders))
.catch((error) => console.error(error))
.finally(() => console.log('finished'));
This is cleaner than deeply nested callbacks, but long chains can still become tiring to read.
Why does async/await exist?
async/await exists to make Promise-based logic read more like a top-to-bottom sequence.
async function run() {
try {
const user = await fetchUser(userId);
const orders = await fetchOrders(user.id);
await saveLog(orders);
} catch (error) {
console.error(error);
}
}
This tends to feel more natural because the reader can follow the workflow in order: get the user, get the orders, save the log.
That is why async/await is so common in production JavaScript code.
Does async/await make code synchronous?
Not really, and this is one of the most important beginner points.
await pauses the local async function flow until the Promise settles, but the overall mechanism is still Promise-based and asynchronous underneath.
So async/await is best thought of as syntax that makes async behavior easier to read, not syntax that turns it into ordinary blocking code.
When should you use Promise chains or async/await?
In many everyday cases, async/await is easier to read. But Promise utilities are still extremely useful.
For example:
- long sequential flow:
async/awaitoften reads better - combining several async operations:
Promise.all()may feel more natural - small follow-up transformations: a short
.then()chain can still be clear
So these are not enemies. async/await sits on top of Promise behavior.
Common mistakes
1. Thinking await automatically improves performance
await is mainly a readability and control-flow tool.
2. Awaiting independent tasks one by one
If tasks do not depend on each other, sequential waiting may be unnecessary.
const [user, posts] = await Promise.all([
fetchUser(userId),
fetchPosts(userId),
]);
3. Ignoring error handling
Whether using Promise chains or async/await, failure paths still need deliberate design.
A good learning exercise
One of the fastest ways to learn this well is to compare the same workflow in three forms:
- callback version
- Promise-chain version
- async/await version
Once that feels comfortable, add a version that groups independent work with Promise.all(). That progression teaches the real concepts much faster than memorizing syntax in isolation.
FAQ
Q. Does an async function always return a Promise?
Yes. Even a normal return value is wrapped in a Promise.
Q. Can await be used anywhere?
Usually it is used inside an async function.
Q. If I learn Promise well, can I skip async/await?
It is better to understand them together. async/await becomes much clearer once Promise itself is understood.
Read Next
- If you want to revisit the broader idea of waiting and flow first, pair this with the Synchronous vs Asynchronous Guide.
- If you want to understand whether the caller itself gets held up, continue with the Blocking vs Non-Blocking Guide.
- If you want to see how the runtime schedules these tasks underneath, the Event Loop Guide is a strong next step.
Start Here
Continue with the core guides that pull steady search traffic.
- Middleware Troubleshooting Guide: Where to Start With Redis, RabbitMQ, or Kafka A practical middleware troubleshooting hub covering how to choose the right first branch when systems using Redis, RabbitMQ, and Kafka show cache drift, queue backlog, or consumer lag.
- Kubernetes CrashLoopBackOff: What to Check First A practical Kubernetes CrashLoopBackOff troubleshooting guide covering startup failures, probe issues, config mistakes, and what to inspect first.
- Technical Blog SEO Checklist for Astro: What to Fix Before You Wait for Traffic A practical Astro SEO checklist for technical blogs covering deployed-site checks, robots.txt, sitemap, canonical, hreflang, structured data, page-role metadata, noindex decisions, and verification commands.
- Canonical and hreflang Setup for Multilingual Blogs: What to Check and What Breaks A practical guide to canonical and hreflang setup for multilingual blogs, covering self-canonicals, reciprocal hreflang clusters, x-default, category pages, rendered HTML checks, and the mistakes that make one language version suppress another.
- OpenAI Codex CLI Setup Guide: Install, Auth, and Your First Task A practical OpenAI Codex CLI setup guide covering installation, sign-in, the first interactive run, Windows notes, and the safest workflow for your first real task.