重新订阅但不缓存错误和完成

时间:2016-01-26 16:23:10

标签: rx-java

我有一个Observable,可以在订阅后执行一些长时间运行的任务。最后,它会发出Boolean代表它是否成功。

我要归档的是,即使取消订阅,任务仍会继续运行,以便完成它的工作。我希望能够重新订阅它,所以它不必从头开始 但是,如果它已由onCompletiononError完成,我想从头开始订阅它,所以我不会选择旧的或错误状态。

我首先认为显而易见的解决方案是使用Observable.cache(),但这不起作用,因为它也会缓存错误。

2 个答案:

答案 0 :(得分:1)

我认为只有RxJava运算符才能解决这个特殊情况,因为半发布半参考需求。我就是这样做的:

AtomicReference<AsyncSubject<Boolean>> result = new AtomicReference<>();

Observable<Boolean> source = Observable.just(1)
        .doOnSubscribe(() -> System.out.println("Source subscribed to"))
        .delay(1, TimeUnit.SECONDS).map(v -> true);

Observable<Boolean> o = Observable.defer(() -> {
    for (;;) {
        AsyncSubject<Boolean> s = result.get();
        if (s == null || s.hasCompleted() || s.hasThrowable()) {
            AsyncSubject<Boolean> s2 = AsyncSubject.create();
            if (result.compareAndSet(s, s2)) {
                source.subscribe(s2);
                return s2;
            }
            continue;
        }
        return s;
    }
});

System.out.println("-- First round");
o.subscribe(System.out::println);
o.subscribe(System.out::println);

Thread.sleep(1100);

System.out.println("-- Second round");
o.subscribe(System.out::println);
o.subscribe(System.out::println);

Thread.sleep(1100);

通过使用原子引用AsyncSubjectdefer,我通过主题发布源Observable的结果,但也确保完成的主题将触发新的订阅。

答案 1 :(得分:0)

您可以使用Observable.retry().cache()重试错误。