JavaScript Async Await
Async and await are keywords that let you write Promise-based code that reads like ordinary, top-to-bottom synchronous code.
The async and await keywords
Async/await is syntax built on top of Promises. Marking a function with async makes it automatically return a Promise, and inside such a function you can use await to pause until a Promise settles. The result is asynchronous code that flows from top to bottom, without chains of .then() calls, while still being non-blocking under the hood.
- An async function always returns a Promise, even if you return a plain value.
- await can only be used inside an async function (or at the top level of a module).
- await pauses that function until the awaited Promise resolves, then gives you its value.
- Errors are handled with a normal try/catch block instead of .catch().
The same task with then vs await
<!DOCTYPE html>
<html>
<body>
<h2>then vs await</h2>
<script>
// Promise chain
function loadUser() {
return fetch("/user/1").then((r) => r.json());
}
// async / await equivalent
async function loadUserAsync() {
const response = await fetch("/user/1");
const user = await response.json();
return user;
}
</script>
</body>
</html>Handling errors with try/catch
Because await unwraps a Promise, a rejected Promise behaves like a thrown error. This means you can wrap awaited calls in a try/catch block, the same way you handle synchronous errors, which keeps success and failure logic close together and easy to read.
Awaiting with error handling
<!DOCTYPE html>
<html>
<body>
<h2>Async Error Handling</h2>
<script>
async function getData() {
try {
const response = await fetch("/data.json");
if (!response.ok) {
throw new Error("Request failed: " + response.status);
}
const data = await response.json();
return data;
} catch (error) {
console.log("Could not load data:", error.message);
return null;
} finally {
console.log("Attempt finished");
}
}
</script>
</body>
</html>Running work in parallel
When independent tasks can run at the same time, start them first and await them together with Promise.all(). This runs them concurrently instead of one at a time, which can dramatically reduce total waiting time.
Sequential vs parallel awaits
<!DOCTYPE html>
<html>
<body>
<h2>Sequential vs Parallel Awaits</h2>
<script>
// Slow: waits for each in turn
async function slow() {
const a = await getUser();
const b = await getPosts();
return [a, b];
}
// Fast: both start immediately, then await together
async function fast() {
const [a, b] = await Promise.all([getUser(), getPosts()]);
return [a, b];
}
</script>
</body>
</html>Exercise: JavaScript Async
What actually happens when the `await` keyword is used inside an async function?