我有一个Observable
,可以在订阅后执行一些长时间运行的任务。最后,它会发出Boolean
代表它是否成功。
我要归档的是,即使取消订阅,任务仍会继续运行,以便完成它的工作。我希望能够重新订阅它,所以它不必从头开始
但是,如果它已由onCompletion
或onError
完成,我想从头开始订阅它,所以我不会选择旧的或错误状态。
我首先认为显而易见的解决方案是使用Observable.cache()
,但这不起作用,因为它也会缓存错误。
答案 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);
通过使用原子引用AsyncSubject
和defer
,我通过主题发布源Observable的结果,但也确保完成的主题将触发新的订阅。
答案 1 :(得分:0)
您可以使用Observable.retry().cache()
重试错误。