# ReadableStream

The `ReadableStream` interface is part of the Streams API of Azion Runtime. It reads a stream of data one chunk at a time, such as the byte data of a response body. The [Fetch API](/en/documentation/devtools/runtime/api-reference/fetch/) provides a specific instance of `ReadableStream`: the `body` property of a [Response](/en/documentation/devtools/runtime/api-reference/response/) object. For more information, refer to [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) on MDN Web Docs.

---

## Constructor

The [`ReadableStream()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream) constructor creates and returns a readable stream object from the handlers you pass to it:

```javascript
new ReadableStream(handlers)
```

The `handlers` object takes a `start(controller)` method and a `cancel(reason)` method. In `start()`, `controller.enqueue()` adds a chunk to the stream and `controller.close()` ends it. The `cancel()` method receives the reason passed to `stream.cancel()`. Chunks are not limited to bytes: a stream you construct can carry strings or numbers. To create a byte stream, add `type: 'bytes'` to the `handlers` object. The [Example](#example) section shows a stream built this way.

---

## Properties

| Property                                                                           | Type    | Description                                                                                                            |
| ---------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| [`locked`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/locked) | Boolean | `true` while a reader holds the stream. It is `false` before `getReader()` and after the reader calls `releaseLock()`. |

---

## Methods

| Method                                                                                                         | Description                                                                                                                                                                                                                                                                                   |
| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`stream.cancel(reason)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/cancel)              | Returns a promise that resolves when the stream is canceled. A call signals that the consumer has lost interest in the stream. The `cancel()` handler of the stream receives `reason` and can use it or ignore it.                                                                            |
| [`stream.getReader()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/getReader)              | Creates a reader and locks the stream to it. While the stream is locked, you cannot acquire another reader until the first one is released. For the methods of the reader, refer to [ReadableStreamDefaultReader](/en/documentation/devtools/runtime/api-reference/readable-default-reader/). |
| [`stream.pipeThrough(transform)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/pipeThrough) | Pipes the stream through a transform stream, or through any other pair of a writable and a readable stream, and returns the readable side. The call is chainable.                                                                                                                             |
| [`stream.pipeTo(destination)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/pipeTo)         | Pipes the stream to a `WritableStream`. Returns a promise that fulfills when the piping completes, or rejects when an error occurs.                                                                                                                                                           |
| [`stream.tee()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/tee)                          | Splits the stream into two branches and returns them as an array of two `ReadableStream` instances. Each branch receives the same chunks.                                                                                                                                                     |

`ReadableStream` also implements the [async iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols), so a [for await...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop reads the chunks of a stream in order.

---

## Example

This handler constructs a stream of two chunks, reads it with a reader, releases the reader, and returns the `locked` value at each stage with the three results of `read()`:

```javascript
export default {
  async fetch(request, env, ctx) {
    const stream = new ReadableStream({
      start(controller) {
        controller.enqueue('a');
        controller.enqueue('b');
        controller.close();
      },
    });
    const lockedBefore = stream.locked;
    const reader = stream.getReader();
    const lockedAfter = stream.locked;
    const r1 = await reader.read();
    const r2 = await reader.read();
    const r3 = await reader.read();
    reader.releaseLock();
    return Response.json({
      lockedBefore,
      lockedAfter,
      reads: [r1, r2, r3],
      lockedAfterRelease: stream.locked,
    });
  },
};
```

The function returns these values. The third `read()` reports `done` as `true` after the stream closes, and `"[undefined]"` marks its `value`, which is `undefined`:

```json
{
 "lockedBefore": false,
 "lockedAfter": true,
 "reads": [
  {
   "value": "a",
   "done": false
  },
  {
   "value": "b",
   "done": false
  },
  {
   "value": "[undefined]",
   "done": true
  }
 ],
 "lockedAfterRelease": false
}
```

---

## Related resources

- [Response](/en/documentation/devtools/runtime/api-reference/response.md): The response object whose `body` property is a `ReadableStream`.
- [ReadableStreamDefaultReader](/en/documentation/devtools/runtime/api-reference/readable-default-reader.md): The reader that `getReader()` locks to a stream, and its methods.
- [ReadableStreamBYOBReader](/en/documentation/devtools/runtime/api-reference/readable-byob-reader.md): The reader that reads a byte stream into a buffer you supply.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
