JavaScript Async Await
An async function lets asynchronous steps read from top to bottom. await waits for a Promise inside that function. It does not freeze the page or stop unrelated JavaScript.
What await pauses
When execution reaches await, that async function yields control. Other event handlers and scripts may continue. Once the Promise fulfills, the function resumes with its value.
Every async call returns a Promise
An async function always returns a Promise. Returning a string fulfills that Promise with the string; throwing an error rejects it. The caller must use await or then to read the eventual value.
Read the result after await
In this example, pour returns a Promise. serve writes waiting, waits for that Promise, and only then receives lida tea.
function pour(order) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if (order === "") reject("no leaves");
else resolve(order + " tea");
}, 100);
});
}
async function serve() {
console.log("waiting");
let drink = await pour("lida");
console.log(drink);
}
serve();
The logs are waiting and then lida tea. Both lines belong to serve, but the second runs after the Promise fulfills.
The caller receives a Promise
Calling serve() without await does not produce the drink directly.
async function serve() {
return "lida tea";
}
let ticket = serve();
console.log(ticket instanceof Promise);
The log is true. ticket is a Promise. An outer async function could use await ticket; ordinary code could use ticket.then(...).
Handle rejection with try and catch
An awaited rejection behaves like a thrown error at the await expression. Put the awaited operation inside try and read the reason in catch.
function pour(order) {
return order === ""
? Promise.reject("no leaves")
: Promise.resolve(order + " tea");
}
async function serveEmpty() {
try {
await pour("");
} catch (reason) {
console.log(reason);
}
}
serveEmpty();
The log is no leaves. Errors thrown after an await in the same try block would also reach this catch.
The rest of the page keeps working
Only the current async function pauses at await. Calling it returns a Promise immediately, so synchronous code after the call can continue.
A complete browser demo
The page records each stage inside one async function. The Promise resolves in a timer so the pause is visible without using a server.
<!DOCTYPE html>
<html>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(resolve => setTimeout(() => resolve(order + " tea"), 100));
}
async function serve() {
const cup = document.getElementById("cup");
const seen = ["waiting"];
cup.textContent = "waiting";
const drink = await pour("lida");
cup.textContent = drink;
seen.push(drink, "done");
document.getElementById("line").textContent = seen.join(" / ");
}
serve();
</script>
</body>
</html>
The final line is waiting / lida tea / done. done is added only after the awaited value has been written.
Try it yourself
Change lida to another name, then await the returned Promise. Next, pass an empty string and confirm that catch receives no leaves.
Common mistakes
Do not expect an async call to return a plain string. Do not place await in a regular function. Most importantly, do not assume that one await stops the whole page.
Remember
async always means a Promise return value. await pauses only that async function until the Promise settles. Use try/catch when the operation can reject.
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top