TransformStream

TransformStream interface of the Streams API represents a set of transformable data.

构造函数

TransformStream()
Creates and returns a transform stream object from the given handlers.

特性

TransformStream.readable 只读
readable end of a TransformStream.
TransformStream.writable 只读
writable end of a TransformStream.

方法

None

范例

Anything-to-uint8array stream

In the following example, a transform stream passes through all chunks it receives as Uint8Array values.

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 ('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("Cannot send a symbol as a chunk part")
        break
      case 'undefined':
        controller.error("Cannot send undefined as a chunk part")
      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()})
  }
}
					

Polyfilling TextEncoderStream and TextDecoderStream

Note that this is deprecated by the native constructors. This is intended as a polyfill for unsupported platforms.

const tes = {
  start(){this.encoder = new TextEncoder()},
  transform(chunk, controller) {
    controller.enqueue(this.encoder.encode(chunk))
  }
}
let _jstes_wm = new WeakMap(); /* info holder */
class JSTextEncoderStream extends TransformStream {
  constructor() {
    let t = {...tes}
    super(t)
    _jstes_wm.set(this, t)
  }
  get encoding() {return _jstes_wm.get(this).encoder.encoding}
}
					

Similarly, TextDecoderStream can be written as such:

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(); /* info holder */
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}
}
					

Chaining multiple ReadableStreams together

This is a useful one, where multiple streams can be conjoined. Examples include building a PWA with progressive loading and progressive streaming.

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()
)
					

Note that this is not resilient to other influences.

规范

规范 状态 Comment

The definition of 'TransformStream' in that specification.
实时标准 初始定义

浏览器兼容性

更新 GitHub 上的兼容性数据
Desktop Mobile
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet
TransformStream Chrome 67 Edge 79 Firefox 不支持 No IE 不支持 No Opera 54 Safari 不支持 No WebView Android 67 Chrome Android 67 Firefox Android 不支持 No Opera Android 48 Safari iOS 不支持 No Samsung Internet Android 9.0
TransformStream() 构造函数 Chrome 67 Edge 79 Firefox 不支持 No IE 不支持 No Opera 54 Safari 不支持 No WebView Android 67 Chrome Android 67 Firefox Android 不支持 No Opera Android 48 Safari iOS 不支持 No Samsung Internet Android 9.0
readable Chrome 67 Edge 79 Firefox 不支持 No IE 不支持 No Opera 54 Safari 不支持 No WebView Android 67 Chrome Android 67 Firefox Android 不支持 No Opera Android 48 Safari iOS 不支持 No Samsung Internet Android 9.0
writable Chrome 67 Edge 79 Firefox 不支持 No IE 不支持 No Opera 54 Safari 不支持 No WebView Android 67 Chrome Android 67 Firefox Android 不支持 No Opera Android 48 Safari iOS 不支持 No Samsung Internet Android 9.0

图例

完整支持
完整支持
不支持
不支持

另请参阅