Course contentsShow
← Node.js
Lesson 212 of 1,9803. Asynchronous Patterns and Flow ControlFree lesson

Lazy Evaluation with Async Generators

You will implement demand-driven data retrieval to reduce unnecessary I/O in your Node.js applications.

In this lesson, you will learn how to use Async Generators to fetch data only when it is explicitly requested, preventing expensive I/O operations from running upfront.

Why "Lazy" Matters

In Node.js, we often deal with large datasets or heavy API calls. If you fetch 1,000 records from a database when you only need to process the first three, you waste memory and bandwidth. Lazy evaluation solves this by delaying the "work" until the exact moment an item is requested by an await for...of loop.

The Mechanism

An Async Generator doesn't execute its logic when called; it returns an iterator. The code inside the generator pauses at every yield statement. The next step of the logic only resumes when the consumer calls .next() (which happens automatically in a loop).

Consider this example where we fetch rows from a database:

async function* fetchDatabaseRows(ids) {
  for (const id of ids) {
    // This expensive I/O only runs when the loop asks for the next item
    const row = await db.query(`SELECT * FROM users WHERE id = ${id}`);
    yield row;
  }
}

// Usage
const stream = fetchDatabaseRows([1, 2, 3, 4, 5]);

// We only process the first 2. The database calls for IDs 3, 4, and 5 
// are never triggered, saving us unnecessary network and CPU load.
for await (const user of stream) {
  console.log(user);
  if (user.id === 2) break; 
}

Preventing Unnecessary I/O

By wrapping your I/O logic in an Async Generator, your application stays reactive. Instead of preparing a massive array of results in memory (which can crash your process with large sets), you create a "pull" pipeline. The consumer "pulls" data one piece at a time. If the consumer stops iterating, the generator stops running, and no further I/O operations are initiated. This pattern is essential for building memory-efficient, high-performance Node.js services that handle streaming data or large-scale file processing.

Key Takeaway: Lazy evaluation with Async Generators ensures that your application only performs the I/O work absolutely required to fulfill the current iteration request, minimizing memory usage and unnecessary network calls.