You’re reading the English version of this content since no translation exists yet for this locale. Help us translate this article!
The for await...of
statement creates a loop iterating over async iterable objects as well as on sync iterables, including: built-in String
, Array
, Array
-like objects (e.g., arguments
or NodeList
), TypedArray
, Map
, Set
, and user-defined async/sync iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Syntax
for await (variable of iterable) { statement }
variable
- On each iteration a value of a different property is assigned to variable. variable may be declared with
const
,let
, orvar
. iterable
- Object whose iterable properties are to be iterated over.
Iterating over async iterables
You can also iterate over an object that explicitly implements async iterable protocol:
var asyncIterable = { [Symbol.asyncIterator]() { return { i: 0, next() { if (this.i < 3) { return Promise.resolve({ value: this.i++, done: false }); } return Promise.resolve({ done: true }); } }; } }; (async function() { for await (let num of asyncIterable) { console.log(num); } })(); // 0 // 1 // 2
Iterating over async generators
Since async generators implement async Iterator protocol, they can be looped using for await... of
async function* asyncGenerator() { var i = 0; while (i < 3) { yield i++; } } (async function() { for await (let num of asyncGenerator()) { console.log(num); } })(); // 0 // 1 // 2
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 iterator for a stream of data, then uses it to find the size of the response from the API.
async function* streamAsyncIterator(stream) { const reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) { return; } yield value; } } finally { reader.releaseLock(); } } // Fetches data from url and calculates response size using the async generator. async function getResponseSize(url) { const response = await fetch(url); // Will hold the size of the response, in bytes. let responseSize = 0; // The for-await-of loop. Async iterates over each portion of the response. for await (const chunk of streamAsyncIterator(response.body)) { // Incrementing the total response length. responseSize += chunk.length; } console.log(`Response Size: ${responseSize} bytes`); // expected output: "Response Size: 1071472" return responseSize; } getResponseSize('https://jsonplaceholder.typicode.com/photos');
Specifications
Browser compatibility
Desktop | Mobile | Server | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
for await...of | Chrome Full support 63 | Edge No support No | Firefox Full support 57 | IE No support No | Opera Full support 50 | Safari Full support 11 | WebView Android Full support 63 | Chrome Android Full support 63 | Firefox Android Full support 57 | Opera Android Full support 46 | Safari iOS ? | Samsung Internet Android Full support 8.0 | nodejs
Full support
10.0.0
|
Legend
- Full support
- Full support
- No support
- No support
- Compatibility unknown
- Compatibility unknown
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
- User must explicitly enable this feature.
- User must explicitly enable this feature.