RxJava计算爆炸
我在CombineTest上遇到了一个棘手的问题。 我正在构建一个巨大的CombineTest链,从我的主要观测值的第二项开始,计算量激增RxJava计算爆炸,java,rx-java,Java,Rx Java,我在CombineTest上遇到了一个棘手的问题。 我正在构建一个巨大的CombineTest链,从我的主要观测值的第二项开始,计算量激增 import org.testng.annotations.Test; import rx.Observable; import rx.observers.TestSubscriber; import rx.subjects.PublishSubject; import rx.subjects.Subject; import java.util.List;
import org.testng.annotations.Test;
import rx.Observable;
import rx.observers.TestSubscriber;
import rx.subjects.PublishSubject;
import rx.subjects.Subject;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class RxTest {
private AtomicInteger ai = new AtomicInteger(0);
private AtomicInteger ai2 = new AtomicInteger(0);
@Test
public void explosion() {
Subject<Integer, Integer> sub = PublishSubject.create();
Observable<Integer> ret = getObservable(2, sub);
TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>();
ret.subscribe(testSubscriber);
sub.onNext(1);
sub.onNext(2); // may be commented
sub.onCompleted();
testSubscriber.assertNoErrors();
List<Integer> numbers = testSubscriber.getOnNextEvents();
System.out.println(numbers.size());
System.out.println(ai);
System.out.println(ai2);
}
private Observable<Integer> getObservable(int depth, Observable<Integer> source) {
if (depth == 0) {
return source;
} else {
Observable<Integer> o = getObservable(depth - 1, source);
for (int i = 0; i < 300; ++i) {
ai2.incrementAndGet();
o = Observable.combineLatest(
o,
getObservable(depth - 1, source).map((a) -> {
ai.incrementAndGet();
return a;
}),
(a, b) -> a + b
);
}
return o;
}
}
}
有两个:
90602
271200
90600
这似乎是RX的正常行为。但我想知道是否有可能避免这种爆炸。我的目标是获得这种输出(比如为每个值重新创建链)
这段代码是我的问题的一个例子,不是真正的用例
我面临的事实是,构建可观察对象是快速的(并且从可观察对象中获得第一个值),但是如果我改变“叶子”可观察对象,它就不是
谢谢我不知道你想在这里做什么,但是你不能用
o.map((a)->{…})
替换combinelatetest
中的第二个参数吗?由于第二次调用getObservable
,您似乎正在进行大量额外的递归。您希望通过递归实现什么?递归目录遍历?目前,没有有效的运算符可用于1.x,但RxJava2Extensions库中有用于2.x的运算符:expand。递归仅用于模拟树。不,我不能用map来代替,因为在我的真实代码中,节点可以随着“叶子”的可观察性而演化。我需要根据可观察到的叶子建造一棵树。这里的问题是,多个节点使用相同的可观察“叶”。一片叶子的变化会产生很多树,而不仅仅是一棵(从叶子到根的繁殖),我终于找到了如何做到这一点。问题是输入combineLatest(两个相同的可观察对象)的变化会发出两个元素,我必须只有一个元素(这不是荒谬的)。为了达到这个目的,我做了一些修改使用序列化操作(非并行)的计划程序-在CombineTest中使用此计划程序进行运行排水(而不是直接从combine调用)-在同一计划程序上可观察到的“叶”可观察,并共享-如果队列中没有更多条目,则仅从CombineTest发出值
90602
271200
90600
2
181200
90600