<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ReadableStream on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestream/</link><description>Recent content in ReadableStream 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/readablestream/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/readablestream/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/readablestream/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/readablestream/&#34;&gt;ReadableStream&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;return-value&#34;&gt;Return value&lt;/h2&gt;
&lt;p&gt;A promise that resolves with the value &lt;code&gt;undefined&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 the stream is locked to a reader.&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();
  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, any enqueued chunks are lost
      await reader.cancel(&amp;#39;cancelling the stream&amp;#39;);
      break;
    }
  }
}

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/readablestream/">ReadableStream&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>getReader()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestream/getreader/</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/readablestream/getreader/</guid><content><![CDATA[&lt;h1 id=&#34;getreader&#34;&gt;getReader()&lt;/h1&gt;
&lt;p&gt;Creates a reader and locks the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestream/&#34;&gt;stream&lt;/a&gt; to it. While the stream is locked, no other reader can be acquired until this one is released.&lt;/p&gt;
&lt;h2 id=&#34;arguments&#34;&gt;Arguments&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;getReader&lt;/code&gt; method takes a single optional &lt;code&gt;options&lt;/code&gt; argument, which is an object with the following properties:&lt;/p&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;Default value&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;mode&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;A property that specifies the type of reader to create. It currently only supports the &lt;code&gt;undefined&lt;/code&gt; value.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;return-value&#34;&gt;Return value&lt;/h2&gt;
&lt;p&gt;A 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestreamdefaultreader/&#34;&gt;ReadableStreamDefaultReader&lt;/a&gt; object instance.&lt;/p&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="getreader">getReader()&lt;/h1>
&lt;p>Creates a reader and locks the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestream/">stream&lt;/a> to it. While the stream is locked, no other reader can be acquired until this one is released.&lt;/p></description></item><item><title>CountQueuingStrategy</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-experimental/streams/readablestream/countqueuingstrategy/</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/readablestream/countqueuingstrategy/</guid><content><![CDATA[&lt;h1 id=&#34;countqueuingstrategy&#34;&gt;CountQueuingStrategy&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;CountQueuingStrategy&lt;/code&gt; interface of the Streams API represents a built-in queuing strategy that counts the number of chunks in the queue.&lt;/p&gt;
&lt;h2 id=&#34;properties&#34;&gt;Properties&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;highWaterMark&lt;/td&gt;
              &lt;td&gt;number&lt;/td&gt;
              &lt;td&gt;The maximum number of chunks that the queue can contain.&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 { CountQueuingStrategy, 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;

  // Using the CountQueuingStrategy to limit the number of chunks in the queue to 5
  const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 5 });

  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);
      },
    },
    queuingStrategy
  );
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="countqueuingstrategy">CountQueuingStrategy&lt;/h1>
&lt;p>The &lt;code>CountQueuingStrategy&lt;/code> interface of the Streams API represents a built-in queuing strategy that counts the number of chunks in the queue.&lt;/p>
&lt;h2 id="properties">Properties&lt;/h2>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>highWaterMark&lt;/td>
&lt;td>number&lt;/td>
&lt;td>The maximum number of chunks that the queue can contain.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>&lt;h2 id="example">Example&lt;/h2>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { CountQueuingStrategy, 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;
// Using the CountQueuingStrategy to limit the number of chunks in the queue to 5
const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 5 });
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);
},
},
queuingStrategy
);
}&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div></description></item></channel></rss>