Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a read only BehaviorSubject interface exist in RX and if not, is it a bad idea to make one?

Implementations of rx provide BehaviorSubject<T> and Variable<T> as mechanisms for modeling properties that change over time (a useful replacement for C# INotifyPropertyChanged).

Generally these are exposed as Observable<T> but it would be more useful to expose properties as something like:

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

This can be created along these lines in 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)
  }

}

Does this already exist? and if not is it because it's against the aims of Rx?

The only way around it is to expose a separate currentValue or write consumers that assume the concrete implementation behind the exposed Observable is a BehaviourSubject or somewhere in the chain a replay() has occured e.g. the following snippet doesn't make it explicit that as soon as I subscribe I will get a value:

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

so code has to be written as if its 'asynchronous' with an underlying assumption it will act in an almost synchronous manner rather than:

class MyViewModel {
  // 'I have a current value and will notify you of changes going forward'
  myProperty:ObservableValue<String> 
}
like image 326
Cargowire Avatar asked Apr 27 '16 16:04

Cargowire


1 Answers

Having thought it over and discussed it a bit more presumably the reason it doesn't (and perhaps shouldn't exist) is that it's an introduction of imperatively accessed state.

Other mechanisms of maintaining state (such as scan) do so within the confines of chained observables rather than as 'dead-end' direct calls such as 'give me the value right now'.

Perhaps it would have it's place in a hybrid reactive/imperative approach but it may just hinder full embracement of the reactive style.

It's analogous to using promises or tasks in half of the code then reverting to synchronous blocking code in other parts.

like image 175
Cargowire Avatar answered Oct 11 '22 12:10

Cargowire