<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ReadableStreamDefaultReader on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/</link><description>Recent content in ReadableStreamDefaultReader on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/index.xml" rel="self" type="application/rss+xml"/><item><title>cancel(reason)</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/cancel/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/cancel/</guid><content><![CDATA[&lt;h1 id=&#34;cancelreason&#34;&gt;cancel(reason)&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;cancel()&lt;/code&gt; method of the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt; interface returns a &lt;code&gt;Promise&lt;/code&gt; that resolves when the stream is canceled.&lt;/p&gt;
&lt;p&gt;Cancel is used when you&amp;rsquo;ve completely finished with the stream and don&amp;rsquo;t need any more data from it, even if chunks are enqueued waiting to be read. That data is lost after &lt;code&gt;cancel&lt;/code&gt; is called, and the stream is not readable any more. To close the stream without getting rid of enqueued chunks, use 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultcontroller/close/&#34;&gt;ReadableStreamDefaultController.close()&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;arguments&#34;&gt;Arguments&lt;/h2&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;reason&lt;/td&gt;
              &lt;td&gt;any&lt;/td&gt;
              &lt;td&gt;An optional human-readable value that represents the reason for canceling the stream.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;returns&#34;&gt;Returns&lt;/h2&gt;
&lt;p&gt;A promise that resolves with the provided &lt;code&gt;reason&lt;/code&gt; when the stream is canceled.&lt;/p&gt;
&lt;h2 id=&#34;exceptions&#34;&gt;Exceptions&lt;/h2&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Exception&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;TypeError&lt;/td&gt;
              &lt;td&gt;Thrown when the source object is not a 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt; or the stream has no owner.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ReadableStream } from &amp;#39;k6/experimental/streams&amp;#39;;
import { setTimeout } from &amp;#39;k6/timers&amp;#39;;

export default async function () {
  // Define a number stream that emits numbers from 1 to 10 every second
  const stream = numbersStream();

  // We use the getReader method to create a reader and lock the stream to it
  const reader = stream.getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    if (value === 8) {
      // Cancel the stream when the number is 8
      await reader.cancel(&amp;#39;cancelling the stream&amp;#39;);
      break;
    }

    console.log(`received number ${value} from stream`);
  }
}

function numbersStream() {
  let currentNumber = 0;

  return new ReadableStream({
    start(controller) {
      const fn = () =&amp;gt; {
        if (currentNumber &amp;lt; 10) {
          controller.enqueue(&amp;#43;&amp;#43;currentNumber);
          setTimeout(fn, 1000);
          return;
        }

        controller.close();
      };
      setTimeout(fn, 1000);
    },
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="cancelreason">cancel(reason)&lt;/h1>
&lt;p>The &lt;code>cancel()&lt;/code> method of the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/">ReadableStreamDefaultReader&lt;/a> interface returns a &lt;code>Promise&lt;/code> that resolves when the stream is canceled.&lt;/p>
&lt;p>Cancel is used when you&amp;rsquo;ve completely finished with the stream and don&amp;rsquo;t need any more data from it, even if chunks are enqueued waiting to be read. That data is lost after &lt;code>cancel&lt;/code> is called, and the stream is not readable any more. To close the stream without getting rid of enqueued chunks, use
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultcontroller/close/">ReadableStreamDefaultController.close()&lt;/a>.&lt;/p></description></item><item><title>read()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/read/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/read/</guid><content><![CDATA[&lt;h1 id=&#34;read&#34;&gt;read()&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;read()&lt;/code&gt; method of the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt; interface returns a promise providing access to the next chunk in the stream&amp;rsquo;s internal queue.&lt;/p&gt;
&lt;h2 id=&#34;returns&#34;&gt;Returns&lt;/h2&gt;
&lt;p&gt;A promise which fullfils or rejects with a value depending on the state of the stream:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a chunk is available, the promise resolves with an object of the form: &lt;code&gt;{ done: false, value: chunkValue }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the stream is closed and no more data is available, the promise resolves with an object of the form: &lt;code&gt;{ done: true, value: undefined }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the stream is errored, the promise rejects with the error that caused the stream to error.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;exceptions&#34;&gt;Exceptions&lt;/h2&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Exception&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;TypeError&lt;/td&gt;
              &lt;td&gt;Thrown when the source object is not a 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt;, the stream has no owner, or 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/releaselock/&#34;&gt;ReadableStreamDefaultReader.releaseLock()&lt;/a&gt; is called.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ReadableStream } from &amp;#39;k6/experimental/streams&amp;#39;;
import { setTimeout } from &amp;#39;k6/timers&amp;#39;;

export default async function () {
  // Define a number stream that emits numbers from 1 to 10 every second
  const stream = numbersStream();

  // We use the getReader method to create a reader and lock the stream to it
  const reader = stream.getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    console.log(`received number ${value} from stream`);
  }
}

function numbersStream() {
  let currentNumber = 0;

  return new ReadableStream({
    start(controller) {
      const fn = () =&amp;gt; {
        if (currentNumber &amp;lt; 10) {
          controller.enqueue(&amp;#43;&amp;#43;currentNumber);
          setTimeout(fn, 1000);
          return;
        }

        controller.close();
      };
      setTimeout(fn, 1000);
    },
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="read">read()&lt;/h1>
&lt;p>The &lt;code>read()&lt;/code> method of the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/">ReadableStreamDefaultReader&lt;/a> interface returns a promise providing access to the next chunk in the stream&amp;rsquo;s internal queue.&lt;/p>
&lt;h2 id="returns">Returns&lt;/h2>
&lt;p>A promise which fullfils or rejects with a value depending on the state of the stream:&lt;/p></description></item><item><title>releaseLock()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/releaselock/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/releaselock/</guid><content><![CDATA[&lt;h1 id=&#34;releaselock&#34;&gt;releaseLock()&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;releaseLock()&lt;/code&gt; method of the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt; interface releases the reader&amp;rsquo;s lock on the stream.&lt;/p&gt;
&lt;p&gt;If the associated stream is errored as the lock is released, the reader will be errored as well. This method is useful when you&amp;rsquo;re done with the stream and want to release the lock on it.&lt;/p&gt;
&lt;p&gt;If the reader&amp;rsquo;s lock is released as pending read operations are still in progress, the reader&amp;rsquo;s 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/read/&#34;&gt;ReadableStreamDefaultReader.read()&lt;/a&gt; calls are immediately rejected with a &lt;code&gt;TypeError&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;exceptions&#34;&gt;Exceptions&lt;/h2&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Exception&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;TypeError&lt;/td&gt;
              &lt;td&gt;Thrown when the source object is not a 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ReadableStream } from &amp;#39;k6/experimental/streams&amp;#39;;
import { setTimeout } from &amp;#39;k6/timers&amp;#39;;

export default async function () {
  // Define a number stream that emits numbers from 1 to 10 every second
  const stream = numbersStream();

  // We use the getReader method to create a reader and lock the stream to it
  const reader = stream.getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
  }

  // Release the lock on the stream, so we&amp;#39;re free to obtain another reader
  // and read from the stream again
  reader.releaseLock();
}

function numbersStream() {
  let currentNumber = 0;

  return new ReadableStream({
    start(controller) {
      const fn = () =&amp;gt; {
        if (currentNumber &amp;lt; 10) {
          controller.enqueue(&amp;#43;&amp;#43;currentNumber);
          setTimeout(fn, 1000);
          return;
        }

        controller.close();
      };
      setTimeout(fn, 1000);
    },
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="releaselock">releaseLock()&lt;/h1>
&lt;p>The &lt;code>releaseLock()&lt;/code> method of the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/">ReadableStreamDefaultReader&lt;/a> interface releases the reader&amp;rsquo;s lock on the stream.&lt;/p>
&lt;p>If the associated stream is errored as the lock is released, the reader will be errored as well. This method is useful when you&amp;rsquo;re done with the stream and want to release the lock on it.&lt;/p></description></item></channel></rss>