TransformStream

Baseline 广泛可用 *

此特性已得到充分确立,可在多种设备和浏览器版本上运行。自 ⁨2022 年 6 月⁩起,所有浏览器均支持此特性。

* 此特性的某些部分可能存在不同级别的支持。

注意:此功能在 Web Workers 中可用。

TransformStream 接口是 Streams API 的一部分,代表了 管道链转换流概念的具体实现。

它可以被传递给 ReadableStream.pipeThrough() 方法,以便将数据流从一种格式转换为另一种格式。例如,它可用于解码(或编码)视频帧、解压缩数据,或将流从 XML 转换为 JSON。

转换算法可以作为可选参数传递给对象构造函数。如果未提供,则在通过流进行管道传输时数据不会被修改。

TransformStream 是一个 可转移对象

构造函数

TransformStream()

创建并返回一个转换流对象,可以选择指定一个转换对象和流的队列策略。

实例属性

TransformStream.readable 只读

TransformStreamreadable 端。

TransformStream.writable 只读

TransformStreamwritable 端。

实例方法

None

示例

任意类型到 Uint8Array 的流

在下面的示例中,一个转换流会将它接收到的所有块作为 Uint8Array 值传递出去。

js
const transformContent = {
  start() {}, // required.
  async transform(chunk, controller) {
    chunk = await chunk;
    switch (typeof chunk) {
      case "object":
        // just say the stream is done I guess
        if (chunk === null) {
          controller.terminate();
        } else if (ArrayBuffer.isView(chunk)) {
          controller.enqueue(
            new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength),
          );
        } else if (
          Array.isArray(chunk) &&
          chunk.every((value) => typeof value === "number")
        ) {
          controller.enqueue(new Uint8Array(chunk));
        } else if (
          typeof chunk.valueOf === "function" &&
          chunk.valueOf() !== chunk
        ) {
          this.transform(chunk.valueOf(), controller); // hack
        } else if ("toJSON" in chunk) {
          this.transform(JSON.stringify(chunk), controller);
        }
        break;
      case "symbol":
        controller.error("Cannot send a symbol as a chunk part");
        break;
      case "undefined":
        controller.error("Cannot send undefined as a chunk part");
        break;
      default:
        controller.enqueue(this.textencoder.encode(String(chunk)));
        break;
    }
  },
  flush() {
    /* do any destructor work here */
  },
};

class AnyToU8Stream extends TransformStream {
  constructor() {
    super({ ...transformContent, textencoder: new TextEncoder() });
  }
}

链式连接多个 ReadableStream

这是一个很有用的场景,可以连接多个流。例如,构建一个具有渐进加载和渐进式流式传输功能的 PWA。

js
let responses = [
  /* conjoined response tree */
];
let { readable, writable } = new TransformStream();

responses.reduce(
  (a, res, i, arr) =>
    a.then(() => res.pipeTo(writable, { preventClose: i + 1 !== arr.length })),
  Promise.resolve(),
);

请注意,这并不能抵抗其他影响。

规范

规范
Streams
# ts-class

浏览器兼容性

另见