【问题标题】:What is the best way to define logic for web-streams sources/sinks?为网络流源/接收器定义逻辑的最佳方法是什么?
【发布时间】:2019-09-05 19:48:30
【问题描述】:

我正在使用新的 web-streams-polyfill,但我不清楚为网络流定义和/或添加扩展功能的最佳方式。尤其是在流的寿命较长的情况下。

特别是,作为一个体面的例子,我想使用 webRTC 数据通道作为可读流源。此数据通道可以通过背压或编程方式暂停。

我在规范和实验中都发现了一些可能的模式:

  1. 扩展流类:
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 方法。

  1. 单独定义源,包装源作为流使用:
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 }
}

在这种模式中,额外的方法被附加到源,而不是流,这使得不那么引人注目,但可能更明确 接口。

  1. 只需使用使用流的自定义类,但实际上不是源:
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


    【解决方案1】:

    我建议使用选项 3 的变体,使用名为 readable 的 getter 来返回流,以与 Web 标准保持一致。

    有关此类 API 的示例,请参阅 https://wicg.github.io/web-transport/#incomingstream

    选项 1 将提供良好的易用性,但我不喜欢使用实现的继承,而且正如您所提到的,构建它会很棘手。

    选项 2 对我来说就像很多样板。

    startpullcancel 未在 ReadableStream 对象上公开的原因是为了在创建流的 API 和使用流的 API 之间提供清晰的分离。

    Jake Archibald 的“2016 - 网络流之年”是我所知道的关于如何“在流中思考”的最佳文章,但我很想听听其他文章。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多