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.
- ReadableStream
- ReadableStreamDefaultReader
- ReadableStreamBYOBReader
- ReadableStreamDefaultController
- ReadableByteStreamController
- ReadableStreamBYOBRequest
- WritableStream
- WritableStreamDefaultWriter
- WritableStreamDefaultController
- TransformStream
- TransformStreamDefaultController
- ByteLengthQueuingStrategy
- CountQueuingStrategy
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"
}