前端读取 readableStream 流数据

44 阅读1分钟

在服务端的系统中, 经常会出现接口返回的数据有几十 KB 大小, 常常会采用流式数据(readableStream)格式返回。

前端就需要获取到完整的数据,然后才能进行下一步的处理, 这里就介绍一下 js 在浏览器环境中获取数据的方法。

const getData = async () => {
  const response = await fetch('https://api.test.com/users/data');
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  // 创建一个可读流
  const reader = response.body.getReader();
  // 读取流数据
  const rs = new ReadableStream({
    start(controller) {
      function push() {
        reader.read().then(({ done, value }) => {
          if (done) {
            // 没有更多数据,关闭流
            controller.close();
            return;
          }
          // 将数据块推送到流中
          controller.enqueue(value);
          // 继续读取下一个数据块
          push();
        });
      }
      push();
    },
  });

  let result = '';

  const fn = async () => {
    const { done, value } = await rs.getReader().read();
    if(done) {
      return
    }
    result += new TextDecoder().decode(value, { stream: true });
    await fn()
  }

  await fn()
  return result;
}

TextDecoder

TextDecoder 是文本解码器, 用于将字节流转为特定编码的文本, 比如 utf-8 格式的文本。

TextDecoder 就只提供了 一个方法 decode

decode()
decode(buffer)
decode(buffer, options)

其中 buffer 是一个 ArrayBuffer、TypedArray 或包含要解码的编码文本的 DataView 对象。

options 是一个对象, 只包含一个属性 stream,一个布尔标志,表示在后续调用 decode() 将跟随附加数据。如果以分块的形式处理数据,则设置为 true;如果是最终的分块或者数据没有分块,则设置为 false。默认是 false