Bird
Raised Fist0
Denoframework~10 mins

Streaming with ReadableStream and WritableStream in Deno - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Streaming with ReadableStream and WritableStream
Create ReadableStream
↓
Start reading chunks
↓
Process each chunk
↓
Write chunk to WritableStream
↓
Repeat until no more chunks
↓
Close WritableStream
↓
Streaming complete
This flow shows how data flows from a ReadableStream, chunk by chunk, into a WritableStream until all data is processed and the writable stream closes.
Execution Sample
Deno
const readable = new ReadableStream({
  start(controller) {
    controller.enqueue('Hello ');
    controller.enqueue('World!');
    controller.close();
  }
});

const writable = new WritableStream({
  write(chunk) { console.log(chunk); }
});

readable.pipeTo(writable);
This code creates a readable stream that sends two text chunks and a writable stream that logs each chunk. Then it pipes the readable to the writable.
Execution Table
StepActionReadableStream StateChunk ProcessedWritableStream ActionOutput
1ReadableStream start calledReadableStream openNoneNoneNone
2Enqueue 'Hello 'ReadableStream has 1 chunkNoneNoneNone
3Enqueue 'World!'ReadableStream has 2 chunksNoneNoneNone
4Close ReadableStreamReadableStream closedNoneNoneNone
5Pipe starts: read first chunkReadableStream closedHello WritableStream write calledConsole logs 'Hello '
6Pipe continues: read second chunkReadableStream closedWorld!WritableStream write calledConsole logs 'World!'
7No more chunks, close WritableStreamReadableStream closedNoneWritableStream close calledNone
8Pipe completeReadableStream closedNoneWritableStream closedNone
💡 All chunks read and written; streams closed; piping finished.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 5After Step 6Final
ReadableStream chunks[]['Hello ']['Hello ', 'World!']['World!'][][]
WritableStream statewritablewritablewritablewritablewritableclosed
Key Moments - 2 Insights
Why does the writable stream only start writing after the readable stream closes?
The writable stream starts writing as soon as the first chunk is available (see Step 5). The readable stream closing (Step 4) means no more chunks will come, but writing begins as soon as chunks are enqueued.
What happens if the readable stream never calls close()?
The writable stream will keep waiting for more chunks and won't close (see Step 7). The pipeTo() promise won't resolve until the readable stream closes.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what chunk is processed at Step 6?
A'Hello '
BNo chunk processed
C'World!'
DBoth chunks together
💡 Hint
Check the 'Chunk Processed' column at Step 6 in the execution_table.
At which step does the writable stream close?
AStep 7
BStep 4
CStep 5
DStep 8
💡 Hint
Look at the 'WritableStream Action' column for when it says 'WritableStream close called'.
If the readable stream enqueued a third chunk before closing, how would the 'ReadableStream chunks' variable change after Step 3?
AIt would still have 2 chunks
BIt would have 3 chunks
CIt would be empty
DIt would have 1 chunk
💡 Hint
Refer to the variable_tracker row for 'ReadableStream chunks' after Step 3.
Concept Snapshot
ReadableStream produces data chunks asynchronously.
WritableStream consumes chunks and processes them.
Use pipeTo() to connect readable to writable.
Chunks flow one by one until readable closes.
Writable closes after all chunks are written.
This enables efficient streaming of data.
Full Transcript
This lesson shows how a ReadableStream sends data chunks to a WritableStream. First, the readable stream is created and enqueues two text chunks: 'Hello ' and 'World!'. Then it closes to signal no more data. The writable stream is created to log each chunk it receives. Using pipeTo(), the readable stream sends chunks one by one to the writable stream. Each chunk is logged as it arrives. When all chunks are sent, the writable stream closes. The execution table traces each step: starting streams, enqueuing chunks, reading and writing chunks, and closing streams. The variable tracker shows how the chunks list shrinks as chunks are processed and how the writable stream state changes from open to closed. Key moments clarify that writing starts as soon as chunks are available, not only after closing, and that the writable stream waits for the readable to close before finishing. The quiz tests understanding of chunk processing order, stream closing steps, and how adding chunks affects state. This visual trace helps beginners see streaming as a flow of data chunks through connected streams, making asynchronous data handling easier to grasp.

Practice

(1/5)
1. What is the main purpose of a ReadableStream in Deno?
easy
A. To accept data chunks that can be written
B. To produce data chunks that can be read
C. To store data permanently
D. To convert data into JSON format

Solution

  1. Step 1: Understand the role of ReadableStream

    A ReadableStream is designed to produce data chunks that can be read by consumers.
  2. Step 2: Differentiate from WritableStream

    A WritableStream accepts data chunks to be written, which is the opposite role.
  3. Final Answer:

    To produce data chunks that can be read -> Option B
  4. Quick Check:

    ReadableStream produces data = A [OK]
Hint: ReadableStream produces data; WritableStream consumes data [OK]
Common Mistakes:
  • Confusing ReadableStream with WritableStream
  • Thinking streams store data permanently
  • Assuming streams convert data formats automatically
2. Which of the following is the correct way to create a new WritableStream in Deno?
easy
A. const stream = new WritableStream({ write(chunk) { console.log(chunk); } });
B. const stream = WritableStream.write(chunk => console.log(chunk));
C. const stream = new WritableStream.write(chunk => console.log(chunk));
D. const stream = WritableStream({ write(chunk) { console.log(chunk); } });

Solution

  1. Step 1: Recall WritableStream constructor syntax

    WritableStream is created with new WritableStream() and an object with a write method.
  2. Step 2: Check each option's syntax

    const stream = new WritableStream({ write(chunk) { console.log(chunk); } }); correctly uses new WritableStream({ write(chunk) { ... } }). Others misuse syntax or omit new.
  3. Final Answer:

    const stream = new WritableStream({ write(chunk) { console.log(chunk); } }); -> Option A
  4. Quick Check:

    WritableStream needs new + write method object = C [OK]
Hint: Use 'new WritableStream' with an object having a write method [OK]
Common Mistakes:
  • Omitting 'new' keyword
  • Calling WritableStream as a function
  • Passing a function directly instead of an object
3. What will the following code output in Deno?
const readable = new ReadableStream({
  start(controller) {
    controller.enqueue('Hello');
    controller.enqueue('World');
    controller.close();
  }
});

const reader = readable.getReader();

(async () => {
  let result = '';
  while(true) {
    const { done, value } = await reader.read();
    if (done) break;
    result += value + ' ';
  }
  console.log(result.trim());
})();
medium
A. Error: reader.read is not a function
B. HelloWorld
C. Hello World
D. undefined

Solution

  1. Step 1: Understand the ReadableStream setup

    The stream enqueues two chunks: 'Hello' and 'World', then closes.
  2. Step 2: Analyze the reading loop

    The loop reads each chunk, appends it with a space to result, and stops when done is true.
  3. Step 3: Output after trimming

    After reading both chunks, result is 'Hello World ' which trims to 'Hello World'.
  4. Final Answer:

    Hello World -> Option C
  5. Quick Check:

    Chunks read and concatenated with space = D [OK]
Hint: ReadableStream chunks read sequentially, concatenated with spaces [OK]
Common Mistakes:
  • Forgetting to await reader.read()
  • Not trimming the final string
  • Assuming chunks concatenate without spaces
4. Identify the error in this Deno code using streams:
const writable = new WritableStream({
  write(chunk) {
    console.log(chunk.toUpperCase());
  }
});

const writer = writable.getWriter();

await writer.write(123);
await writer.close();
medium
A. write method must be async
B. Missing await before new WritableStream
C. getWriter() is not a function
D. Cannot call toUpperCase on a number

Solution

  1. Step 1: Check the write method usage

    The write method calls chunk.toUpperCase(), which only works on strings.
  2. Step 2: Analyze the write call argument

    The code writes the number 123, which has no toUpperCase() method, causing a runtime error.
  3. Final Answer:

    Cannot call toUpperCase on a number -> Option D
  4. Quick Check:

    toUpperCase on number causes error = A [OK]
Hint: Check data types before calling string methods [OK]
Common Mistakes:
  • Assuming write must be async
  • Thinking getWriter() is invalid
  • Missing await on WritableStream creation
5. You want to transform a ReadableStream of text chunks to uppercase and write them to a WritableStream. Which approach correctly implements this in Deno?
hard
A. Pipe the readable through a TransformStream that uppercases chunks, then pipe to writable
B. Directly write chunks from readable to writable without transformation
C. Use readable.getReader() and writable.getWriter(), but forget to release locks
D. Convert chunks to uppercase after writing to writable

Solution

  1. Step 1: Understand stream transformation

    To modify data between readable and writable, use a TransformStream that changes chunks to uppercase.
  2. Step 2: Use pipeThrough and pipeTo methods

    Pipe the readable stream through the transform, then pipe the result to the writable stream for correct flow and backpressure handling.
  3. Step 3: Evaluate other options

    Directly write chunks from readable to writable without transformation skips transformation, C risks locking issues, and D transforms too late after writing.
  4. Final Answer:

    Pipe the readable through a TransformStream that uppercases chunks, then pipe to writable -> Option A
  5. Quick Check:

    Use TransformStream + pipeThrough + pipeTo = B [OK]
Hint: Use TransformStream between readable and writable for data changes [OK]
Common Mistakes:
  • Skipping TransformStream for data modification
  • Not handling stream locks properly
  • Transforming data after writing
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard