以下是链:observableOne.flatMap(event -> observableTwo).subscribe()
我希望在第一次发出事件时从observableOne
中获取事件,然后忽略此Observable
中的所有其他事件,直到observableTwo
发出值为止,完成或完成错误。值得一提的是,我最终对第二个Observable的事件感兴趣。
上下文就像是,Button
点击了一个事件被触发,这是ObservableOne
。触发事件触发ObservableTwo
,让我们说它是一系列网络操作。因此,我希望在执行网络操作时忽略所有按钮单击。
答案 0 :(得分:0)
要控制flatMap
所做的请求金额,请使用特殊的重载:
observableOne
.doOnRequest(System.out::println)
.flatMap(event -> observableTwo, 1)
.flatMap(event -> observableThree, 1)
.subscribe()
如果您的来源observableOne
,observableTwo
,observableThree
是同步的,那么这不是必需的,但对于异步来源,这应该可以胜任。
答案 1 :(得分:0)
[Edit2]问题已经改变,所以我调整了答案+实际上给出了正确的答案
我没有看到其他方式,而不是状态标志:
AtomicBoolean progress = new AtomicBoolean();
observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
)
.subscribe();
如果发生错误,您的订阅将被取消,即使再次点击该按钮,您也不会再收到任何活动。
如果这不是你想要的,你可以:
重新订阅错误回调
private void bindRemoteCalls() {
if (mySubscription != null) mySubscription.unsubscribe();
AtomicBoolean progress = new AtomicBoolean();
mySubscription = observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
)
.flatMap(event -> observableTwo, 1)
.subscribe(
data -> handleResponse(data),
error -> {
handleError(error);
bindRemoteCalls();
}
);
}
使用onErrorReturn()
(与doOnError()
结合使用来实际做点什么)
AtomicBoolean progress = new AtomicBoolean();
observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
.doOnError(error -> handleError(error))
.onErrorReturn(null)
.filter(data -> data != null)
)
.subscribe(data -> handleResponse(data));
如果需要,请记住将subscribeOn()
/ observeOn()
与正确的调度程序一起使用。
请考虑使用switchMap()
代替flatMap()
- >如果再次按下该按钮,则取消前一个呼叫(取消订阅),然后启动一个新呼叫。或者以Rx术语说:observableTwo以前的订阅已取消订阅并且会形成新的订阅。
如果在取消订阅时禁用按钮并在终止时启用它,则可以通过使按钮不可点击轻松获得相同的结果。
答案 2 :(得分:0)
您可以使用Flowable
而不是Observable
,然后可以通过设置observableTwo
使用背压来达到所需的效果(直到maxConcurrency
终止的丢弃事件)从flatMap
到1
:
observableOne
.toFlowable(BackpressureStrategy.DROP)
.flatMap(event -> observableTwo.toFlowable(BackpressureStrategy.ERROR), 1)
.subscribe();
结果证明,akarnokd在RxJava2Extensions库中也有一个专门用于此目的的ObservableTransformer
。可以这样使用:
observableOne
.compose(ObservableTransformers.flatMapDrop(event -> observableTwo))
.subscribe();