Async and Await
async and await let you write promise-based code that reads top to bottom like ordinary synchronous code.
On this page · 5 min · Intermediate
On this page
- Learning objectives
- Explanation
- Visual explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 1, 2026
Learning objectives#
- Declare async functions
- Pause on promises with await
- Handle errors with try/catch
- Avoid accidental sequential waits
Explanation#
An async function always returns a promise. Inside it, await pauses that function until the awaited promise settles, then gives you its value.
If the awaited promise rejects, await throws, so you handle errors with an ordinary try/catch.
await only pauses the current async function, not the whole program. Other code — click handlers, timers — keeps running.
Visual explanation#
Syntax#
async function load() {
try {
const value = await somePromise;
} catch (error) {
// handle the rejection
}
}
Code example: Sequential vs parallel awaits#
const wait = (ms, value) => new Promise(r => setTimeout(() => r(value), ms));
async function sequential() {
const start = Date.now();
const a = await wait(300, 'A');
const b = await wait(300, 'B');
console.log(a, b, 'sequential ~', Math.round((Date.now() - start) / 100) * 100, 'ms');
}
async function parallel() {
const start = Date.now();
const [a, b] = await Promise.all([wait(300, 'A'), wait(300, 'B')]);
console.log(a, b, 'parallel ~', Math.round((Date.now() - start) / 100) * 100, 'ms');
}
async function main() {
await sequential();
await parallel();
try {
await Promise.reject(new Error('Network down'));
} catch (err) {
console.log('Caught:', err.message);
}
}
main();
A B sequential ~ 600 ms A B parallel ~ 300 ms Caught: Network down
Step-by-step explanation#
- wait() returns a promise that resolves after the given delay.
- In sequential(), the second wait does not start until the first finishes — about 600ms total.
- In parallel(), both promises are created first and awaited together with Promise.all — about 300ms.
- A rejected promise makes await throw, so try/catch catches it like any other error.
Real-world use case#
Loading a dashboard that needs a user profile, notifications and settings: start all three requests and await Promise.all to cut the loading time.
Common mistakes#
forEach does not wait for async callbacks. Use for…of for sequential work or Promise.all(items.map(...)) for parallel work.
Without await you get a pending Promise object, not the value.
Best practices#
- Wrap awaits in try/catch where you can handle the error meaningfully
- Start independent requests before awaiting them
- Use for…of with await for ordered, sequential work
- Check response.ok when using fetch — it does not reject on HTTP errors
Remember this#
async functions always return a promise.
await pauses until the promise settles.
Use try/catch around await for errors.
Practice exercise#
Your task: Rewrite this with async/await: fetchUser(1).then(u => console.log(u.name)).catch(e => console.log(e.message));
Show solution
async function showUser() {
try {
const user = await fetchUser(1);
console.log(user.name);
} catch (e) {
console.log(e.message);
}
}
showUser();
Mini quiz#
What does an async function always return?
Want more? Practise all JavaScript MCQs · JavaScript interview questions
My notes#
Saved in this browser.