JS Async/Await
In this page:
The async Keyword
Placing async before a function declaration marks it as asynchronous, allowing the use of await inside it, and automatically making the function itself return a promise, even if it looks like it returns a plain value.
Note: Any function that needs to use await, anywhere inside it, must itself be declared with the async keyword.
Warning: An async function always returns a promise, even a simple return text; inside it actually returns a promise that resolves to that text.
Example: The async Keyword
async function getValue() {
return 42;
}
getValue().then(v => console.log(v)); // async function returns a promise
The await Keyword
await pauses an async function's execution at that exact line until the promise it's waiting on settles, then resumes with the resolved value, letting asynchronous code read in a natural, sequential order.
Note: await only pauses the async function it's inside, the rest of the page and any other code continues running normally in the meantime.
Warning: Using await on a value that isn't a promise still works, but it simply resolves immediately, it's not an error, just unnecessary in that case.
Example: The await Keyword
async function run() {
const value = await Promise.resolve(10);
console.log(value);
}
run();
Error Handling With try/catch
Wrapping await statements in a try block lets you catch a rejected promise's error in the matching catch block, providing a clean, familiar way to handle asynchronous errors without chaining .catch().
Note: try/catch around await reads very similarly to handling errors in regular synchronous code, which is one of async/await's biggest readability advantages.
Warning: An await inside a try block that isn't actually followed by a matching catch still throws normally, uncaught errors in async functions can silently fail elsewhere.
Example: Error Handling With try/catch
async function run() {
try {
await Promise.reject("failed");
} catch (err) {
console.log("Caught:", err);
}
}
run();
async/await vs Promises
async/await is built directly on top of promises, it's essentially a more readable syntax for the same underlying mechanism, which is why the two approaches can be mixed freely, and why understanding promises first makes async/await easier to grasp.
Note: For simple, single-step asynchronous code, either style works well, async/await tends to shine most clearly once you have several sequential steps.
Warning: Since async/await is built on promises, any function you await must still actually return a promise, awaiting a non-promise function doesn't make it asynchronous.
Example: async/await vs Promises
// Same result, two styles:
Promise.resolve(5).then(v => console.log(v));
async function run() {
const v = await Promise.resolve(5);
console.log(v);
}
run();
A Practical Example
Combining async/await with try/catch and multiple sequential steps shows the real strength of this pattern, complex asynchronous logic reads almost like straightforward, synchronous code.
Note: When several async steps genuinely don't depend on each other, use Promise.all with await together rather than awaiting them one at a time unnecessarily.
Warning: Awaiting independent operations sequentially, one after another, when they could run simultaneously, unnecessarily slows down your code.
Example: A Practical Example
async function getUser() {
try {
const id = await Promise.resolve(1);
const name = await Promise.resolve("Sam");
console.log(id, name);
} catch (err) {
console.log("Error:", err);
}
}
getUser();
- Using await outside of a function marked async, which causes a syntax error, await only works inside async functions.
- Forgetting try/catch around an await, an unhandled rejected promise inside an async function throws an error that needs catching.
- Awaiting promises one after another unnecessarily when they don't depend on each other, wasting time that Promise.all could have run in parallel.
- The async keyword marks a function as asynchronous, letting it use await and automatically making it return a promise.
- await pauses execution within an async function until a promise settles, without blocking the rest of the page.
- try/catch is the standard way to handle errors from awaited promises inside an async function.
async/await has been supported in all major browsers since 2017 and is now a standard, widely used part of modern JavaScript.
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS Dates
- JS Math
- JS Conditionals
- JS Switch
- JS Loop For
- JS Loop While
- JS Iterables
- JS Sets
- JS Maps
- JS typeof
- JS Type Conversion
- JS Destructuring
- JS Arrow Functions
- JS Classes
- JS Modules
- JS Promises
- JS Async/Await
- JS DOM
- JS DOM Methods
- JS Events Advanced
- JS DOM Navigation
- JS DOM Collections
- JS Async Callbacks
- JS Async Parallel
- JS Date Set
- JS Set Logic