Rx Java:没有订阅的replay()autoconnect()

时间:2018-06-14 22:03:51

标签: rx-java observable reactive-programming

我对Rx-java很新,我想了解replay() autoConnect()的工作方式。我的代码中存在以下情况,我希望使昂贵的操作更有效率。

public static void main(String[] args) {
    Single<String> observable = getStringObservable().observeOn(Schedulers.io()).toSingle();
    Single<String> observable1 = getStringObservable().observeOn(Schedulers.io()).toSingle();
    String observable2 = getStringObservable().toSingle().toBlocking().value();

    observable.subscribe(s -> System.out.println("Sub1 got: " + s));
    observable1.subscribe(s -> System.out.println("Sub2 got: " + s));
    System.out.println("Sub3 got " + observable2);
}

//This is some expensive operation which is a network call
private static Observable<String> getStringObservable() {
    return Single.just("Event")
                .map(s -> {
                    System.out.println("Expensive operation for " + s);
                    return s;
                }).toObservable().replay().autoConnect();
}

代码的输出是 -

Expensive operation for Event
Expensive operation for Event
Sub1 got: Event
Expensive operation for Event
Sub3 got Event
Sub2 got: Event

我正在寻找更高效的是 -

Expensive operation for Event
Sub1 got: Event
Sub2 got Event
Sub3 got: Event

我对重播autoConnect的理解是它会保存订阅者的响应。我试过autoConnect(3),因为我有三个订阅者,但它似乎没有用。

一些假设 - 上面的代码是我的代码实际上是如何的伪代码。在我的实际代码中,所有三个observable都位于不同的工作流程中,可以按任何顺序调用,如observable&gt;&gt; observable1&gt;&gt; observable2 OR observable2&gt;&gt;可观察的&gt;&gt; observable1等等。

我无法在我的代码中存储任何可以共享的observable状态。

如果您需要更多信息,请与我们联系。

感谢阅读。

2 个答案:

答案 0 :(得分:2)

您可以缓存操作,但是您必须保留对observable的引用,如下所示:

ConnectableObservable<String> cachedObservable = Observable.just("Event")
        .map(s -> {
            System.out.println("Expensive operation for " + s);
            return s;
        }).replay();
cachedObservable.connect();

Single<String> observable = cachedObservable.observeOn(Schedulers.io()).singleOrError();
Single<String> observable1 = cachedObservable.observeOn(Schedulers.io()).singleOrError();
String observable2 = cachedObservable.singleOrError().blockingGet();

observable.subscribe(s -> System.out.println("Sub1 got: " + s));
observable1.subscribe(s -> System.out.println("Sub2 got: " + s));
System.out.println("Sub3 got " + observable2);

打印

Expensive operation for Event
Sub1 got: Event
Sub2 got: Event
Sub3 got Event

如果您真的想将此作为网络操作的缓存,可以使用Guava's memoize缓存observable一段时间:

Supplier<ConnectableObservable<String>> cache = Suppliers.memoizeWithExpiration(() -> {
    ConnectableObservable<String> cached = Observable.just("Event")
            .map(s -> {
                System.out.println("Expensive operation for " + s);
                return s;
            }).replay();
    cached.connect();
    return cached;
}, 1, TimeUnit.MINUTES);

cache.get().subscribe(thing -> doAwesomeStuffWith(thing));

答案 1 :(得分:0)

您需要3个订阅者,但您只创建了一些流,然后阻止第一个消费者,这将阻止其他2个订阅者订阅。首先订阅非阻止的,然后使用阻止的:

Single<String> observable = getStringObservable().observeOn(Schedulers.io()).toSingle();
Single<String> observable1 = getStringObservable().observeOn(Schedulers.io()).toSingle();

observable.subscribe(s -> System.out.println("Sub1 got: " + s));
observable1.subscribe(s -> System.out.println("Sub2 got: " + s));

String observable2 = getStringObservable().toSingle().toBlocking().value();

System.out.println("Sub3 got " + observable2);