在更大的RxJava应用程序中,我有许多热,无限源Observable。这些排放合并后由下游观察员处理。然后,处理结果需要用于临时暂停某些源Observable的排放,而非暂停的Observable预计将继续排放,观察者将消耗非暂停的排放。热点Observables在暂停期间发生的任何事件都可以安全地被忽略/删除。
到目前为止,我能够提出的唯一解决方案是应用具有全局,有状态变量的过滤器。下面的代码显示了原理。为简单起见,我将源Observable的逻辑移动到while循环中,然后简单地随机分配暂停/运行决策。此外,源Observables被简单的区间替换(在实际应用程序中,事件是随机的,来自外部源,包含在Observables中)
boolean is1running = true;
boolean is2running = true;
boolean is3running = true;
public void multiStream() {
Observable<String> ob1 = Observable
.interval(100, TimeUnit.MILLISECONDS)
.map(s -> "OB1::" + s)
.filter(s -> keepRunning(1));
Observable<String> ob2 = Observable
.interval(100, TimeUnit.MILLISECONDS)
.map(s -> "OB2::::" + s)
.filter(s -> keepRunning(2));
Observable<String> ob3 = Observable
.interval(100, TimeUnit.MILLISECONDS)
.map(s -> "OB3:::::" + s)
.filter(s -> keepRunning(3));
Observable<String> finalObs = Observable.merge(ob1, ob2, ob3);
finalObs.subscribe(s -> System.out.println(s));
Random randomGenerator = new Random();
while(true)
{
sleep(1000);
is1running = randomGenerator.nextBoolean();
is2running = randomGenerator.nextBoolean();
is3running = randomGenerator.nextBoolean();
}
}
private boolean keepRunning(int i) {
switch(i)
{
case 1: return is1running;
case 2: return is2running;
case 3: return is3running;
}
return true;
}
代码似乎有效,但我不满意必须使用全局的有状态变量。
这种情况是否有更好的模式,也符合功能和反应范式?
答案 0 :(得分:0)
对于这种情况,我经常使用switchMap()
运算符。对于您的示例,我们假设每个来源都有一个可观察的boolean
,因此ob1Switch
,ob2Switch
和ob3Switch
。然后,
Observable<String> ob1 = Observable
.interval(100, TimeUnit.MILLISECONDS)
.map(s -> "OB1::" + s);
将由ob1Switch
控制:
Observable<String> ob1Switchable = ob1Switch
.switchMap( switchOn -> switchOn ? ob1 : Observable.never() );
现在,您可以在ob1Switchable
使用ob1
,而无需使用全局状态。当你想要ob1Switch
开启时,你必须保持ob1Switch.onNext(Boolean.TRUE)
最新ob1
。
编辑:作为带有反馈循环的链的示例:
Observable<Integer> eventsPerSecond =
Observable.merge( ob1Switchable, ob2Switchable, ob3Switchable)
.buffer(1, TimeUnit.SECONDS )
.map( buf -> buf.size() );
Observable<Boolean> obs1Switch = eventsPerSecond
.map( eps -> Boolean.valueOf( eps > LOW_THRESHOLD );
Observable<Boolean> obs2Switch = eventsPerSecond
.map( eps -> Boolean.valueOf( eps > MEDIUM_THRESHOLD );
Observable<Boolean> obs3Switch = eventsPerSecond
.map( eps -> Boolean.valueOf( eps > HIGH_THRESHOLD );
有了这些定义,你就可以有一个反馈循环,在你有可持续的事件发生率之前连续关闭来源。