Problem: Asynchronous Streaming Adapter

Hard
40 min
Adapt a callback-based file reader into an async iterator interface that works with for await...of.

Problem statement

You maintain a legacy file reader utility that processes data in chunks. It uses a callback pattern to push each chunk of data, as shown:

legacyReader.readFile('log.txt', chunk => { ... });

Modern code in your app expects an async iterator that it can loop over using:

for await (const chunk of reader) { ... }

You need to write an adapter that makes the legacy callback-based reader compatible with this newer iteration model—without modifying the original code.

Goal

Implement a StreamAdapter class that wraps a legacy reader and exposes an async iterable interface.

for await (const chunk of new StreamAdapter(legacyReader, 'file.txt')) { ... }

The adapter should:

  • Use an internal queue to store incoming chunks.

  • Resolve iteration as chunks arrive.

  • End gracefully when the legacy reader signals completion.

Constraints

  • You cannot modify the legacy reader.

  • The adapter must implement the [Symbol.asyncIterator]() protocol.

  • It must work seamlessly inside for await...of.

  • Assume the legacy reader calls the callback with null when the stream ends.

Sample output

The examples below illustrate what the output should look like:

(async () => {
const stream = new StreamAdapter(legacyReader, 'log.txt');
for await (const chunk of stream) {
console.log('Chunk:', chunk);
}
console.log('Done reading.');
})();
/* Expected output:
Chunk: [2025-10-10 10:00:12] INFO Server started on port 3000
[2025-10-10 10:00:14] INFO Connected to database successfully
[2025-10-10 10:00:18] WARN High memory usage detected
[2025-10-10 10:00:22] ERROR Failed to fetch user profile
[2025-10-10 10:00:25] INFO Request completed in 213ms
Done reading.
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Understanding the async iterator protocol

Problem: Asynchronous Streaming Adapter

Hard
40 min
Adapt a callback-based file reader into an async iterator interface that works with for await...of.

Problem statement

You maintain a legacy file reader utility that processes data in chunks. It uses a callback pattern to push each chunk of data, as shown:

legacyReader.readFile('log.txt', chunk => { ... });

Modern code in your app expects an async iterator that it can loop over using:

for await (const chunk of reader) { ... }

You need to write an adapter that makes the legacy callback-based reader compatible with this newer iteration model—without modifying the original code.

Goal

Implement a StreamAdapter class that wraps a legacy reader and exposes an async iterable interface.

for await (const chunk of new StreamAdapter(legacyReader, 'file.txt')) { ... }

The adapter should:

  • Use an internal queue to store incoming chunks.

  • Resolve iteration as chunks arrive.

  • End gracefully when the legacy reader signals completion.

Constraints

  • You cannot modify the legacy reader.

  • The adapter must implement the [Symbol.asyncIterator]() protocol.

  • It must work seamlessly inside for await...of.

  • Assume the legacy reader calls the callback with null when the stream ends.

Sample output

The examples below illustrate what the output should look like:

(async () => {
const stream = new StreamAdapter(legacyReader, 'log.txt');
for await (const chunk of stream) {
console.log('Chunk:', chunk);
}
console.log('Done reading.');
})();
/* Expected output:
Chunk: [2025-10-10 10:00:12] INFO Server started on port 3000
[2025-10-10 10:00:14] INFO Connected to database successfully
[2025-10-10 10:00:18] WARN High memory usage detected
[2025-10-10 10:00:22] ERROR Failed to fetch user profile
[2025-10-10 10:00:25] INFO Request completed in 213ms
Done reading.
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Understanding the async iterator protocol

Node.js
[2025-10-10 10:00:12] INFO Server started on port 3000
[2025-10-10 10:00:14] INFO Connected to database successfully
[2025-10-10 10:00:18] WARN High memory usage detected
[2025-10-10 10:00:22] ERROR Failed to fetch user profile
[2025-10-10 10:00:25] INFO Request completed in 213ms