理解@metamask/object-multiplex包
@metamask/object-multiplex 是 MetaMask 提供的一个基于objectMode的流多路复用库.
用于将多条流整合到同一个流中处理,在同一个流中同时处理多种不同类型的数据通道(即多路复用)。
ObjectMultiplex继承于readable-stream[1]的Duplex
对比
使用ObjectMultiplex 多个流同时经过一个处理流
不使用ObjectMultiplex时:
1 | const streamA = new Duplex(...) |
使用ObjectMultiplex时, 注意transformStream需开启objectMode(因为ObjectMultiplex使用对象形式传输数据)
1 | import { Transform } from 'readable-stream'; |
头尾同一流的意义
metamask出现很多头尾同一流
1 | mux.pipe(streamA).pipe(mux) |
- mux.pipe(streamA): 将 mux 的输出(分发后的数据)发送到 streamA
- streamA.pipe(mux): 将 streamA 的输入(通道的数据)发送回 mux, 让 mux 收集并分发。
mux 需要从 streamA 中收集数据,同时将数据发送给 streamA。这构成了一个完整的循环
实现了双向通信: 需要既发送又接收数据,形成完整的通信链路
双向通信
streamA流和transformStream流可以相互通信
1 | import { Transform } from 'readable-stream'; |
streamA 或mux 写入数据 传给 transform流
1 | // mux.pipe(transformStream).pipe(mux) |
数据流向大概是:
- streamA的
_write触发, 内部调用this._parent.push(即是mux的push函数) - mux的_read触发
- 因pipe连接mux的可读流数据 触发transformStream的transform, transform内触发this.push
- 因pipe连接transformStream的可读流数据 触发mux的_write
- mux的_write 即而触发 streamA的 _read
1 | // 此时需改成以streamA 连接,因为mux.write是往streamA的可读流添加数据 |
数据流向大概是:
- mux的
_write触发, 内部substreams['streamA'] 触发streamA的push函数 - streamA的_read触发
- 因pipe连接streamA的可读流数据 触发transformStream的transform, transform内触发this.push
- 因pipe连接transformStream的可读流数据 触发streamA的_write
- streamA的_write 即而触发streamA的
_parent(即是mux)的push函数, 即而触发 mux的 _read
transform流 写入数据 传给 streamA
1 | // mux.pipe(transformStream).pipe(mux) |
数据流向大概是:
- transformStream的transform触发,transform内触发this.push
- 因pipe连接mux流,transformStream的可读流数据 触发mux流的_write
- mux流的write触发 内部substreams['streamA'] 触发streamA的push函数
- 继而 streamA的_read触发
源码

- 1.readable-stream是Node.js官方出的库,旨在提供Streams模块的兼容性实现。允许开发者在不同的Node.js版本中使用一致的
StreamsAPI,同时也为浏览器环境提供支持 ↩