Loading...

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.

Await inside serve

javascript
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.

An async call returns a Promise

javascript
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.

Catch an awaited rejection

javascript
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.

Complete async page

html
<!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

Ready to Start

Test Your Knowledge

Challenge yourself with this interactive quiz and see how well you understand the topic

❓
6
Questions
🎯
70%
To Pass
♾️
∞
Time
🔄
∞
Attempts

📝 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