Regular iterators work for synchronous data.
But what about:
- API responses
- File streams
- WebSockets
- Large data pipelines
That’s where Async Iterators shine.
## 🔹 What Is an Async Iterator?
An async iterator returns a Promise from `next()`.
Instead of:
```js
iterator.next();
You get:
await iterator.next();
🔹 Async Generator Basics
async function* fetchData() {
yield await fetch("/api/1").then(r => r.json());
yield await fetch("/api/2").then(r => r.json());
}
Notice the async function*.
🔹 Using for await…of
for await (const data of fetchData()) {
console.log(data);
}
This automatically waits for each Promise.
🔹 Why Not Just Use Promise.all?
Promise.all waits for everything at once.
Async Iterators:
• Process data progressively
• Reduce memory usage
• Improve responsiveness
🔹 Example: Simulated Streaming
async function* delayed() {
let i = 0;
while (i < 3) {
await new Promise(r => setTimeout(r, 1000));
yield i++;
}
}
Values arrive gradually.
🔹 Async Iterator Protocol
An object is async iterable if it implements:
Symbol.asyncIterator
Example:
const obj = {
async *[Symbol.asyncIterator]() {
yield 1;
yield 2;
}
};
🔹 Sync vs Async Iterators
| Feature | Iterator (Sync) | Async Iterator |
|---|---|---|
next() returns | value | Promise |
for...of | ✅ | ❌ |
for await...of | ❌ | ✅ |
| Streaming | ⚠️ | ✅ |
🔹 Real-World Use Cases
• Fetch streaming APIs
• Node.js streams
• Pagination handling
• Event processing
• Real-time dashboards
🔹 When to Use Async Iterators
Use when:
• Data arrives over time
• You need progressive processing
• Memory efficiency matters
Avoid when:
• All data is already available
• Simple async/await is enough
🎯 Final Thought
Sync iterators walk through data.
Async iterators wait for it.
Async Iterators let JavaScript handle streaming data elegantly.