我已经获得以下代码来修改我的源observable,以便在应用程序状态在ENABLED和DISABLED之间切换时断开连接并重新连接。
但是,如果我的sourceObservable本身有一个调用完成的情况,我怀疑它会立即重新连接,因为这个变换器会重复,如果应用程序状态仍然是ENABLED。
是否有一种优雅的解决方法,可能将takeUntil和repeatWhen分组,以便它们不会捕获来自上方的任何完整事件?
N.B。 applicationStatusObservable根据请求重复其最后一个值。
非常感谢帮助:)
/**
* Transforms the source observable so that it defers initial subscription until the service becomes available,
* unsubscribes when the service becomes unavailable, and resubscribes when the service becomes available again.
*/
public class AvailabilityTransformer<T> implements Observable.Transformer<T, T> {
private final Observable<ApplicationStatus> applicationStatusObservable;
AvailabilityTransformer(final Observable<ApplicationStatus> applicationStatusObservable) {
this.applicationStatusObservable = applicationStatusObservable;
}
@Override
public Observable<T> call(final Observable<T> sourceObservable) {
final Observable<ApplicationStatus> applicationEnabledObservable =
applicationStatusObservable.filter(applicationStatus -> applicationStatus == ENABLED);
final Observable<ApplicationStatus> applicationDisabledObservable =
applicationStatusObservable.filter(applicationStatus -> applicationStatus != ENABLED);
return sourceObservable
.takeUntil(applicationDisabledObservable) // Unsubscribe whenever the application is disabled
.repeatWhen(repeatObservable -> repeatObservable.flatMap(repeat ->
applicationEnabledObservable.flatMap(applicationStatus -> just(repeat)))) // Resubscribe when enabled again
.delaySubscription(applicationEnabledObservable.first()); // Delay the initial subscription until the application is first enabled
}
}
答案 0 :(得分:0)
他,
我花了一些时间来了解你在做什么。我希望我终于明白了。您有一个热的observable isApplicationAvailable,它将告诉订阅者应用程序是启用还是禁用(true / false)。你有其他的observable,它们正在做一些工作(可能是热/冷)并希望它们只产生值,如果observable isApplicationAvailable返回true。如果某些reaseon应用程序被禁用,则observables不应生成任何值。
我使用RxJava2进行测试。
在此示例中,如果observable isApplicationActive返回true,stringObservable将仅将值传递给订阅者。
@Test
public void name() throws Exception {
Subject<Boolean> isApplicationActive = BehaviorSubject.<Boolean>create()
.toSerialized();
Observable<Boolean> isApplicationActiveObservable = isApplicationActive
.hide()
.doOnNext(s -> System.out.println("isApplicationActive: " + s));
isApplicationActive.onNext(false);
Thread.sleep(1_000);
Observable<String> stringObservable = Observable.interval(1_000, TimeUnit.MILLISECONDS)
.map(Objects::toString)
.doOnNext(s -> System.out.println("NextIntervalValue"))
.compose(createSwitchMapCompose(isApplicationActiveObservable));
stringObservable.subscribe(s -> {
System.out.println("stringObservable: " + s);
});
Thread.sleep(2_000);
isApplicationActive.onNext(true);
Thread.sleep(2_000);
isApplicationActive.onNext(false);
Thread.sleep(2_000);
isApplicationActive.onNext(true);
Thread.sleep(6_000);
isApplicationActive.onNext(false);
Thread.sleep(20_000);
}
private ObservableTransformer<String, String> createSwitchMapCompose(Observable<Boolean> isApplicationActiveObservable) {
return upstream -> upstream.switchMap(s -> isApplicationActiveObservable.take(1).flatMap(aBoolean -> {
if (aBoolean) {
return Observable.just(s);
}
return Observable.empty();
})
);
}