Get to know MDN better
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
The for await...of statement creates a loop iterating over async iterable objects as well as sync iterables. This statement can only be used in contexts where await can be used, which includes inside an async function body and in a module.
Receives a value from the sequence on each iteration. May be either a declaration with const, let, or var, or an assignment target (e.g., a previously declared variable, an object property, or a destructuring pattern). Variables declared with var are not local to the loop, i.e., they are in the same scope the for await...of loop is in.
iterableAn async iterable or sync iterable. The source of the sequence of values on which the loop operates.
statementA statement to be executed on every iteration. May reference variable. You can use a block statement to execute multiple statements.
When a for await...of loop iterates over an iterable, it first gets the iterable's [Symbol.asyncIterator]() method and calls it, which returns an async iterator. If the @asyncIterator method does not exist, it then looks for a [Symbol.iterator]() method, which returns a sync iterator. The sync iterator returned is then wrapped into an async iterator by wrapping every object returned from the next(), return(), and throw() methods into a resolved or rejected promise, with the value property resolved if it's also a promise. The loop then repeatedly calls the final async iterator's next() method and awaits the returned promise, producing the sequence of values to be assigned to variable.
A for await...of loop exits when the iterator has completed (the awaited next() result is an object with done: true). Like other looping statements, you can use control flow statements inside statement:
If the for await...of loop exited early (e.g., a break statement is encountered or an error is thrown), the return() method of the iterator is called to perform any cleanup. The returned promise is awaited before the loop exits.
for await...of generally functions the same as the for...of loop and shares many of the same syntax and semantics. There are a few differences:
Like for...of, if you use a using declaration, then the variable cannot be called of:
This is to avoid syntax ambiguity with the valid code for await (using of []), before using was introduced.
You can also iterate over an object that explicitly implements async iterable protocol:
Since the return values of async generator functions conform to the async iterable protocol, they can be looped using for await...of.
For a more concrete example of iterating over an async generator using for await...of, consider iterating over data from an API.
This example first creates an async iterable for a stream of data, then uses it to find the size of the response from the API.
for await...of loop also consumes sync iterables and generators. In that case it internally awaits emitted values before assign them to the loop control variable.
Note: Be aware of yielding rejected promises from a sync generator. In such case, for await...of throws when consuming the rejected promise and DOESN'T CALL finally blocks within that generator. This can be undesirable if you need to free some allocated resources with try/finally.
To make finally blocks of a sync generator always called, use the appropriate form of the loop — for await...of for the async generator and for...of for the sync one — and await yielded promises explicitly inside the loop.
| ECMAScript® 2027 Language Specification # sec-for-in-and-for-of-statements |
Enable JavaScript to view this browser compatibility table.
This page was last modified on Oct 30, 2025 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.