RX 中是否存在只读 BehaviorSubject 接口,如果不存在,创建一个接口是个坏主意吗?



rx 的实现提供了BehaviorSubject<T>Variable<T>作为建模随时间变化的属性的机制(C# INotifyPropertyChanged 的有用替代品)。

通常,这些属性显示为Observable<T>但将属性公开为以下内容会更有用:

class ObservableValue<T> : Observable<T>{
  var currentValue:T { get }
}

这可以沿着这些行在 swift 中创建:

class ObservableValue<Element> : ObservableType {
  typealias E = Element
  private let subject:BehaviorSubject<E>
  var currentValue:E {
      get {
          return try! subject.value()
      }
  }
  init(subject:BehaviorSubject<E>) {
      self.subject = subject
  }
  func subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
      return self.subject.subscribe(observer)
  }

}

这已经存在了吗? 如果不是,是因为它违背了 Rx 的目标吗?

解决它的唯一方法是公开一个单独的currentValue或编写消费者,假设暴露的Observable背后的具体实现是行为主体或链中的某个地方发生了重播(),例如以下代码片段没有明确表示一旦我订阅,我就会得到一个值:

class MyViewModel {
  // 'I will notify you of changes perhaps including my current value'
  myProperty:Observable<String> 
}

因此,代码必须编写得好像它与基本假设"异步"一样,它将以几乎同步的方式运行,而不是:

class MyViewModel {
  // 'I have a current value and will notify you of changes going forward'
  myProperty:ObservableValue<String> 
}

经过深思熟虑并进行了更多的讨论,大概它不存在(也许不应该存在)的原因是它是对命令式访问状态的引入。

其他维护状态的机制(如scan)是在链式可观察量范围内进行的,而不是作为"死胡同"的直接调用,如"现在给我价值"。

也许它会在混合反应式/命令式方法中占有一席之地,但它可能只会阻碍对反应式风格的完全接受。

这类似于在一半的代码中使用承诺或任务,然后在其他部分中恢复为同步阻塞代码。

在大多数情况下,人们所做的是创建一个标准视图模型,该模型通过 INotifyPropertyChanged 公开属性。这允许 UI 元素绑定到它们并接收属性更改事件并保持 UI 同步。

然后,如果您想要所述属性的 IObservable,您可以利用将事件转换为 IObservable 的标准 Rx 运算符。你可以谷歌这个找到很多不同的实现。您通常会从观察视图模型的内容中创建和使用这些可观察量,而不是直接在视图模型上公开它们。

相关内容

  • 没有找到相关文章

最新更新