The basic shape
async function load() {
const res = await fetch("/api/data");
const data = await res.json();
return data;
}
Every async function returns a promise automatically, so callers can await it too.
Handle errors with try/catch
async function load() {
try {
const data = await fetchData();
return data;
} catch (err) {
console.error("Failed:", err);
}
}
A regular try/catch block catches a rejected promise, which is far easier to read than chained .catch() calls.
Run tasks in parallel with Promise.all
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
]);
Awaiting two calls one after another wastes time. Promise.all starts both at once and waits for both to finish.
Common mistakes
- Using
awaitoutside anasyncfunction. It is a syntax error except at the top level of a module. - Awaiting in a loop when calls are independent. Use
Promise.allto run them together. - Forgetting that an async function always returns a promise.
Frequently asked questions
What is the difference between async/await and promises?
They are the same mechanism. async/await is cleaner syntax built on top of promises, so you get the same behaviour with code that reads sequentially.
Can I await a non-promise value?
Yes. await on a plain value simply returns it, so it is safe to await something that may or may not be a promise.
Get comfortable with promises in our free JavaScript course.