TransformStream - 表示一组可转换的数据

TransformStreamStreams API 的接口表示一组可转换的数据。

构造函数

TransformStream()

从给定的处理程序创建并返回一个转换流对象。

属性

TransformStream.readable 只读

TransformStreamreadable 端。

TransformStream.writable 只读

TransformStreamwritable 端。

方法

无。

实例

转换任意值为 Uint8Array

在以下实例中,转换流将其接收的所有块作为 Uint8Array 值进行传递。

const transformContent = {
  start() {}, // 必要的。
  async transform(chunk, controller) {
    chunk = await chunk
    switch (typeof chunk) {
      case 'object':
        // 认为流完成了
        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 ('function' === typeof chunk.valueOf && 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("无法将符号作为块部分进行发送")
        break
      case 'undefined':
        controller.error("无法将 undefined 作为块部分进行发送")
      default:
        controller.enqueue(this.textencoder.encode(String(chunk)))
        break
  },
  flush() { /* 在这里做任何销毁的工作 */ }
}

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

实现 TextEncoderStreamTextDecoderStream 的 Polyfill

注意,原生构造函数已弃用此方法。这是一个 polyfill 适用于不受支持的平台。

const tes = {
  start(){this.encoder = new TextEncoder()},
  transform(chunk, controller) {
    controller.enqueue(this.encoder.encode(chunk))
  }
}
let _jstes_wm = new WeakMap(); /* 用于信息存储 */
class JSTextEncoderStream extends TransformStream {
  constructor() {
    let t = {...tes}

    super(t)
    _jstes_wm.set(this, t)
  }
  get encoding() {return _jstes_wm.get(this).encoder.encoding}
}

类似地,TextDecoderStream 可以这样编写:

const tes = {
  start(){
    this.decoder = new TextDecoder(this.encoding, this.options)
  },
  transform(chunk, controller) {
    controller.enqueue(this.decoder.decode(chunk))
  }
}
let _jstds_wm = new WeakMap(); /* 用于信息存储 */
class JSTextDecoderStream extends TransformStream {
  constructor(encoding = 'utf-8', {...options} = {}) {
    let t = {...tds, encoding, options}

    super(t)
    _jstes_wm.set(this, t)
  }
  get encoding() {return _jstds_wm.get(this).decoder.encoding}
  get fatal() {return _jstds_wm.get(this).decoder.fatal}
  get ignoreBOM() {return _jstds_wm.get(this).decoder.ignoreBOM}
}

将多个 ReadableStreams 链接在一起

这是一个很有用的方法,可以将多个流连接在一起。实例包括使用渐进加载和渐进流构建 PWA。

let responses = [ /* 联合响应树 */ ]
let {readable, writable} = new TransformStream

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

规范

规范 状态 备注
Streams
TransformStream 的定义
现行的标准 初始定义

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持6779 不支持 不支持54 不支持
TransformStream() 构造函数6779 不支持 不支持54 不支持
readable6779 不支持 不支持54 不支持
writable6779 不支持 不支持54 不支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持6767 未知 不支持 未知48 不支持
TransformStream() 构造函数6767 未知 不支持 未知48 不支持
readable6767 未知 不支持 未知48 不支持
writable6767 未知 不支持 未知48 不支持

相关链接