【发布时间】:2019-09-05 19:48:30
【问题描述】:
我正在使用新的 web-streams-polyfill,但我不清楚为网络流定义和/或添加扩展功能的最佳方式。尤其是在流的寿命较长的情况下。
特别是,作为一个体面的例子,我想使用 webRTC 数据通道作为可读流源。此数据通道可以通过背压或编程方式暂停。
我在规范和实验中都发现了一些可能的模式:
- 扩展流类:
class DataChannelStream extends ReadableStream {
constructor(dataChannel) {
super({
// source methods (cant use `this`)
start: () => { ... }
pull: () => { ... }
cancel: () => { ... }
})
this.dataChannel = dataChannel
}
// extra methods
pause() { ... }
resume() { ... }
}
我遇到的一个问题是必须将源方法传递到super 而不引用this,这是必需的,因为它在super 调用之前。一个好处似乎是您的结果流将直接在其上具有额外的 pause/resume 方法。
- 单独定义源,包装源作为流使用:
class DataChannelSource {
constructor(dataChannel) {
this.dataChannel = dataChannel
}
// source methods
start: () => { ... }
pull: () => { ... }
cancel: () => { ... }
// extra methods
pause() { ... }
resume() { ... }
}
// elsewhere....
function createDataChannelStream (dataChannel) {
const source = new DataChannelSource(dataChannel)
const stream = new ReadableStream(source)
return { source, stream }
}
在这种模式中,额外的方法被附加到源,而不是流,这使得不那么引人注目,但可能更明确 接口。
- 只需使用使用流的自定义类,但实际上不是源:
class DataChannelSource {
constructor(dataChannel) {
this.dataChannel = dataChannel
}
pipeTo(dest) {
const stream = new ReadableStream({
// source methods
start: () => { ... }
pull: () => { ... }
cancel: () => { ... }
})
return stream.pipeTo(dest)
}
// extra methods
pause() { ... }
resume() { ... }
}
我不太喜欢在这里重新定义pipeTo api,但我们也可以只做getStream 之类的操作并返回流。
最后一点,我有点希望我们可以扩展基类并将源方法定义为子类的成员,而不必将它们传递给super。不允许这种设计有充分的理由吗?
class DataChannelStream extends ReadableStream {
constructor(dataChannel) {
super()
this.dataChannel = dataChannel
}
// source methods
start: () => { ... }
pull: () => { ... }
cancel: () => { ... }
// extra methods
pause() { ... }
resume() { ... }
}
鉴于上述示例,前三种模式似乎有效,但显然提供了不同的 API。所以它可能最终归结为品味/设计。
我想知道是否有人可以帮助指导我的预期用途,或者是否有人提出了最佳做法。
【问题讨论】:
标签: javascript stream