Async Iterators

Async iterators allow you to iterate over data sources that produce values asynchronously, such as streams, network requests, or timers. They combine the iteration protocol with asynchronous operations using for await...of loops.

Illustration of Async Iterators
Illustration of Async Iterators

💡 What are Async Iterators?

Async iterators implement the Symbol.asyncIterator method and return a promise resolving to an object with { value, done }.

Unlike regular iterators, async iterators return promises for each iteration step, enabling asynchronous data consumption.

Synchronous vs Asynchronous Iterators
FeatureSynchronous IteratorAsync Iterator
SymbolSymbol.iteratorSymbol.asyncIterator
Return value from next()Object {value, done}Promise<{value, done}>
Usagefor...offor await...of

Async Iterator Example

Here is a minimal async iterator that yields values with delays:

📌 Deep Dive: Async Iterator with Delay

JAVASCRIPT
const asyncIterable = {
  async *[Symbol.asyncIterator]() {
    for (let i = 1; i <= 3; i++) {
      await new Promise(resolve => setTimeout(resolve, 500)); // delay 500ms
      yield i;
    }
  }
};

(async () => {
  for await (const num of asyncIterable) {
    console.log(num);
  }
})();
// Output after ~500ms intervals: 1 2 3

💡 Using async generators

Async iterators are often implemented via async generator functions using async function*(). This simplifies yielding promises sequentially.

When to Use Async Iterators

  • Reading data streams (files, network)
  • Consuming APIs that deliver chunks or events over time
  • Handling timers or delayed data asynchronously

⚠️ Important

You must use for await...of to consume async iterators. Regular for...of loops do not await promises and will not work correctly.

Manual Async Iterator Usage

You can manually access async iterator's next() method, which returns a promise:

📌 Deep Dive: Manual Async Iterator Consumption

JAVASCRIPT
async function manualConsume(asyncIterable) {
  const iterator = asyncIterable[Symbol.asyncIterator]();

  while (true) {
    const { value, done } = await iterator.next();
    if (done) break;
    console.log(value);
  }
}

manualConsume(asyncIterable);

💡 Summary

  • Async iterators return promises from next().
  • Use for await...of to loop through asynchronous data.
  • Async generator functions simplify creating async iterators.