Asynchronous Iteration

An async iterable has a [Symbol.asyncIterator]() method whose iterator's next() returns a promise of { value, done } (the synchronous protocol is in Iterables and Iterators). for await...of, allowed in async functions and modules, awaits each step, and an async function* generator is the easiest way to produce one. It fits data that arrives in pieces: paginated APIs, streams, Node's readline and events.on().

Paging through a simulated API with an async generatorJavaScriptLive
async function* pages() {                        // like a paginated REST API
  try {
    for (let page = 1; ; page++) {
      await new Promise(resolve => setTimeout(resolve, 10));   // simulated request
      yield [`item${page}a`, `item${page}b`];
    }
  } finally { console.log("cleanup"); }
}
for await (const items of pages()) { console.log(items); if (items[0] === "item2a") break; }

Pages load only when the loop asks, and break calls the iterator's return(), so finally runs. Array.fromAsync(iterable) (ECMAScript 2026, in browsers since January 2024) collects a finite async iterable into an array one value at a time.