The javascript await operator waits for a Promise (or thenable) to settle and returns the fulfilled value inside an async function—or at the top level of an ES module. Pairing js await with async is the usual way to write async await javascript that reads like synchronous control flow. For how promises resolve and reject in the first place, see JavaScript Promise.resolve and JavaScript Promise.reject.
Tested on: all examples in this tutorial were run with Node.js v20.18.2, and the output shown below each snippet is its exact console output. Examples use the JavaScript
setTimeout()API with a zero delay so you can reproduce results quickly; real code might use larger delays orfetch.
Quick reference
Use this table for where await javascript is valid and for picking sequential vs concurrent await patterns.
| Context | await allowed? |
|---|---|
Inside async function |
Yes |
| Top level of ES module | Yes |
Non-async function / classic script |
No (SyntaxError) |
Basic await promise inside async
Inside an async function, await pauses that function until the promise fulfills (or throws on rejection).
async function example() {
const myPromise = new Promise((resolve) => {
setTimeout(() => {
resolve("hello world");
}, 0);
});
const result = await myPromise;
console.log(result);
}
example();hello worldTwo awaits in a row — sequential timing
Each await waits for its promise before the next line runs. If each delay were 2000 ms, the total would be about 4 seconds, not two—use Promise.all when the work is independent (see below).
async function sequentialExample() {
const promise1 = new Promise((resolve) => {
setTimeout(() => resolve("hello"), 0);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => resolve("world"), 0);
});
const result1 = await promise1;
const result2 = await promise2;
console.log(result1 + " " + result2);
}
sequentialExample();hello worldPromise.all — concurrent await
Start independent promises first, then await Promise.all([...]) so they run concurrently and you still get ordered results in one step. For whichever promise settles first—success or failure—use Promise.race instead.
async function parallelExample() {
const p1 = Promise.resolve("hello");
const p2 = Promise.resolve("world");
const [a, b] = await Promise.all([p1, p2]);
console.log(a + " " + b);
}
parallelExample();hello worldtry / catch with await — rejections
Rejected promises from await propagate like thrown values inside the async function, so wrap risky awaits in try/catch (or handle with .catch on the promise).
async function mayFail() {
try {
await Promise.reject(new Error("bad"));
} catch (e) {
console.log(e.message);
}
}
mayFail();badawait on a non-promise (await operator javascript)
Non-promise values are wrapped with Promise.resolve semantics, so await 5 still yields 5.
async function num() {
console.log(await 5);
}
num();5Top-level await — ES modules only
Top level await javascript is allowed at module scope in ES modules. Save as a .mjs file (or set "type": "module" in package.json) and run with node. If Node throws Cannot use import statement outside a module before your file runs, fix the module goal first—see cannot use import statement outside a module.
Run: The in-page Run sandbox executes a classic script (like a plain
node file.jswithout"type": "module"), so Run is turned off for this fence. Below is what you actually write in an ES module on disk.
const x = await Promise.resolve(42);
console.log(x);42In a classic script without modules, use an async IIFE instead:
(async () => {
const x = await Promise.resolve(42);
console.log(x);
})();42Summary
- Use
awaitonly insideasyncfunctions or at the top level of ES modules; otherwise you get aSyntaxError. - Sequential
awaitruns one settlement after another; usePromise.all(or related helpers) when tasks are independent. - Handle rejections with
try/catcharoundawaitor explicit.catchon the promise chain. awaiton a non-promise usesPromise.resolvesemantics; top-levelawaitneeds a module context or an async IIFE in classic scripts.
References
MDN references for the await operator, async function, and concurrent waiting with Promise.all.
Frequently Asked Questions
Can I use javascript await outside an async function?
In a classic script or non-async function body, await is a SyntaxError. Use an async function, an async arrow IIFE, or top-level await in an ES module (.mjs or type module).
What does await do to a non-promise value?
The expression is converted with Promise.resolve semantics. await 5 yields 5.
How do I handle a rejected await promise?
Use try/catch around the await, or attach .catch to the promise chain. Uncaught rejections inside an async function reject the async function's returned promise.
Is sequential await the same as Promise.all?
No. await one then await another runs the second after the first settles. Promise.all runs the promises concurrently and waits for all—better when they are independent.
What is top level await javascript?
In ES modules, await may appear at the top level of the file. It pauses evaluation of that module for importers that depend on it. It is not supported in plain CommonJS or classic scripts.
Does await block the main thread?
It suspends the current async function until the promise settles, but other tasks timers and I/O can still run; it does not busy-wait the CPU.
