【问题标题】:Transform a hot observable to a cold observable将热可观察对象转换为冷可观察对象
【发布时间】:2015-12-01 21:45:30
【问题描述】:

我正在使用 RxJava 观察数据库表。所有 SQL SELECT 查询都返回一个热的 observable,每当我在同一个表中插入/更新/删除行时,我都会重新运行任何订阅的 SELECT 查询并在热查询 observable 上调用 onNext(queryResult)

database.select("SELECT * FROM Foo) // returns an observable
       .map(doSomething)
       .filter(aFilter)
       .subscribe (
             { 
                 //  onNext
             },
             {
                // onError
             }
          )

这很好用。但是,在一个特殊用例中,我想避免数据库重新发出一个新项目。是否有某种运算符可以用来使其成为单个“冷”可观察对象,而无需更改为像这样的热可观察对象构建的所有数据库层:

database.select("SELECT * FROM Foo) // returns an observable
           .map(doSomething)
           .filter(aFilter)
           .toColdObservable()
           .subscribe (
                 { 
                     //  onNext
                 },
                 {
                    // onError
                 }
              )

我知道“cold observable”这个词不合适,但我还没有找到更好的名字。所以我想要的是数据库不通知 SQL Query Observable 更新。所以我所说的“cold observable”只是查询数据库一次,之后不再接收更新。

【问题讨论】:

  • 根据您的描述,我想知道select() 可能是如何工作的:返回一些BehaviourSubjectPublishSubject,同时安排对数据库的异步查询,同时确保此查询获胜'在当前客户端实际订阅之前不开始将项目推送到主题中?

标签: rx-java


【解决方案1】:

简单的take(1)怎么样?这将在第一个结果之后完成您的可观察查询。

【讨论】:

  • 是的,最明显的并没有立即出现在我的脑海中。所以我的解决方案是结合@akarnokd 和take(1) 的答案
【解决方案2】:

有两种主要方法可以将热的 observable 转换为冷的 observable:defer 完全推迟它的存在,或者 replay + autoConnect(0) 预运行它并作为冷的 observable 重播给其他人。

但是,此select 的通知方案意味着它永远不会完成,因此您需要应用某种timeout,以便重播的大小有限制。

我还会检查该库是否真的支持一次性运行(冷)查询,而您没有此问题;每个订阅者都将运行一个新的有限查询。否则,这可能是一个不错的功能请求。

【讨论】:

    【解决方案3】:

    如果您不希望收到通知,可以使用空的subscribe,它实际上会忽略结果:

    订阅一个 Observable 但忽略它的发射和通知。

    database.select("SELECT * FROM Foo") // returns an observable
               .map(doSomething)
               .filter(aFilter)
               .subscribe ()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多