如何进行不会改变流的副作用订阅?

时间:2016-11-28 18:42:56

标签: rx-java

情景:

我有一个数据列表(业务交易)。如果满足以下两个条件,则认为此数据是陈旧的:

  • 用户(UI / View)订阅了数据源(rx.Observable<List<Transaction>>
  • &gt; =自上次网络同步以来已过去5分钟。该值已序列化并从数据库中观察。

注意:如果UI /视图未订阅数据源,并且&gt; = 5已过去五分钟,我不想同步新数据(因为没有人正在收听)

以下代码示例的一些详细信息:

  • data.observe()返回rx.Observable<List<Transaction>>
  • void syncIfLast5Minutes()将强制检查过去五分钟内是否有同步 - 如果没有,则会执行新的网络请求以获取新数据

现在,我可以轻松地做一些事情:

data.observe()
    .doOnSubscribe(transactions -> syncIfLast5Minutes()

但这只会检查UI的初始订阅数据是否过时。如果在5分钟后仍然订阅了UI,则不会在此处触发自动刷新(但我希望它能够执行)。

我正在寻找一个

的副作用操作符
  • 不影响原始流
  • 订阅会启动一个计时器,该计时器将监控数据何时失效(&gt; =已经过了5分钟)
  • unsusbscribing取消此计时器

在RxJava中是否存在一种惯用的方式来实现这种反应?

1 个答案:

答案 0 :(得分:1)

您可以通过将您的信息流与执行副作用的Observable.interval合并(数据刷新)并应用ignoreElements来实现您的目标。

这是一个有效的例子:

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.subjects.PublishSubject;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        PublishSubject<String> data = PublishSubject.create();
        //refresh data every second for this demo
        //for your use case it's every 5 minutes
        data.mergeWith(Observable.interval(1, TimeUnit.SECONDS) 
                // cause timed side-effect that updates data stream
                .doOnNext(n -> data.onNext(n + "")) 
                .ignoreElements()
                .cast(String.class)) 
            .doOnNext(System.out::println) 
            .toBlocking() 
            .subscribe();
    }

}

如果多个订阅者正在使用该流,您可能需要查看.share,因此每5分钟只会发生一次刷新操作。