RxScala中是否存在阻止onComplete执行的内置操作?
我正在学习响应式编程,若问题较为浅显还请见谅,同时我也欢迎针对设计方案的改进建议。我正在使用scala-swing展示模拟器的结果:一种设置下图表以直方图形式展示,另一种设置下以累积和形式展示(第一种设置中bin1=2、bin2=5、bin3=3;第二种设置中第一个高度为2,第二个为2+5,第三个为2+5+3等)。模拟器运行较慢,最初我使用Future计算数据后设置到图表中,现在尝试采用响应式方案,核心需求:
- 切换展示模式时不重新生成数据;
- 为图表设置一次Observable并让其永久监听该Observable。
尝试的实现与遇到的问题
我曾通过PublishSubject作为链式起点、Future向起点传入数据实现需求:切换展示模式时,创建新的PublishSubject().map(新渲染逻辑).subscribe(图表Observable)。现在我尝试更规范的实现方式,但出现问题,以下是简化后的代码:
val textObservable: Subject[String] = PublishSubject() textObservable.subscribe(text => { println(s"Text: ${text}") }) var textSubscription: Option[Subscription] = None val start = Observable.from(Future { "Base text" }).cache var i = 0 val button = new Button() { text = "Click" reactions += { case event => { i += 1 if (textSubscription.isDefined) { textSubscription.get.unsubscribe() } textSubscription = Some(start.map(((j: Int) => { (base: String) => s"${base} ${j}" })(i)).subscribe(textObservable)) } } }
启动时创建Observable并添加打印文本的逻辑,接着创建包含生成数据的Observable并添加cache操作,以便后续订阅可重放结果。然后创建按钮,点击按钮时会链式添加带有唯一逻辑的中间Observable(该逻辑为生成一个追加当前i值的函数,无法复用),再订阅到第一个Observable以输出最终结果。
理论上cache操作可避免重新生成数据,首次运行正常,但onComplete会被调用到textObservable,导致其无法再次使用。若改为以下订阅方式则可正常运行:
textSubscription = Some(start.map(((j: Int) => { (base: String) => s"${base} ${j}" })(i)).subscribe(text => textObservable.onNext(text)))
这种方式通过手动调用onNext拦截了onComplete的传递,但我认为该方式不够规范,想了解是否有更常规的实现方式或架构方案,以及是否存在内置操作来解决此问题。
内容的提问来源于stack exchange,提问作者Jonathan Card

