Streams

The Streams globals handle data that arrives or is produced in pieces rather than all at once: ReadableStream is a source you read from, WritableStream a destination you write to, and TransformStream a pair of both that processes data in between.

They appear throughout the platform: fetch() response bodies are ReadableStreams, and Blob.stream() returns one. All of the interfaces are available as globals without importing anything.

Readers, writers, and controllers are normally obtained from the streams they belong to, through getReader(), getWriter(), and the start and transform callbacks.

Usage#

Reading a stream — either through the async iterator or a reader:

for await (const chunk of response.body) {
  // chunk is a Uint8Array
  total += chunk.byteLength;
}
const reader = response.body.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  process(value);
}

Creating and consuming your own stream:

const readable = new ReadableStream({
  start(controller) {
    for (const line of lines) controller.enqueue(line);
    controller.close();
  },
});

for await (const chunk of readable) {
  console.log(chunk);
}

Piping through a transform:

const { readable, writable } = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toUpperCase());
  },
});

const writer = writable.getWriter();
await writer.write("hello");

for await (const out of readable) {
  console.log(out); // "HELLO"
}

Documentation#