我是反应性编程的新手,并且对组成具有依赖性的可观察对象感到困惑。这是场景: 有两个可观察量 A , B 。可观察 A 取决于 B 发出的值。 (因此A需要观察B)。有没有办法创建一个Obindleable C 组成 A 和 B ,并发出 V ?我只是在寻找RxJava documentation中的指针。
答案 0 :(得分:1)
关于A如何依赖B,你的问题有点模糊,所以我试着举几个如何组合observable的例子。
示例 - 没有 B 时无法创建 A - 使用map()
public class B {
public final int value;
public B(int value) {
this.value = value;
}
}
public class A {
public final B b;
public A(B b) {
this.b = b;
}
}
public Observable<B> createObservableB() {
return Observable.from(new B(0), new B(1), new B(2), new B(3));
}
public Observable<A> createObservableA() {
return createObservableB()
.map(new Func1<B, A>() {
@Override
public A call(B b) {
return new A(b);
}
});
}
示例 - 每次出现 B 都可以创建零个或多个 A - 使用flatMap()
public class B {
public final int value;
public B(int value) {
this.value = value;
}
}
public class A {
public final int value;
public A(int value) {
this.value = value;
}
}
public Observable<B> createObservableB() {
return Observable.from(new B(0), new B(1), new B(2), new B(3));
}
public Observable<A> createObservableA() {
return createObservableB()
.flatMap(new Func1<B, Observable<? extends A>>() {
@Override
public Observable<? extends A> call(final B b) {
return Observable.create(new Observable.OnSubscribe<A>() {
@Override
public void call(Subscriber<? super A> subscriber) {
for (int i = 0; i < b.value; i++) {
subscriber.onNext(new A(i));
}
subscriber.onCompleted();
}
});
}
});
}
我不确定您对Observables C 和 V 的要求是什么,所以让我们看一下组合observable的更多方法。
示例 - 合并两个可观察对象发出的每对项目 - 使用zip()
public class A {
public final int value;
public A(int value) {
this.value = value;
}
}
public class B {
public final int value;
public B(int value) {
this.value = value;
}
}
public class C {
private final A a;
private final B b;
public C(A a, B b) {
this.a = a;
this.b = b;
}
}
public Observable<B> createObservableB() {
return Observable.from(new B(0), new B(1), new B(2), new B(3));
}
public Observable<A> createObservableA() {
return Observable.from(new A(0), new A(1), new A(2), new A(3));
}
public Observable<C> createObservableC() {
return Observable.zip(createObservableA(), createObservableB(),
new Func2<A, B, C>() {
@Override
public C call(A a, B b) {
return new C(a, b);
}
}
);
}
示例 - 组合两个Observable的最后一项 - 使用combineLatest()
// Use the same class definitions from previous example.
public Observable<C> createObservableC1() {
return Observable.combineLatest(createObservableA(), createObservableB(),
new Func2<A, B, C>() {
@Override
public C call(A a, B b) {
return new C(a, b);
}
}
);
}
答案 1 :(得分:0)
我也是反应式编程的新手,只是将一些可能对你的案例感兴趣的代码放在一起
需要观察B
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Func1;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.testng.Assert.assertTrue;
public class Q22284380TestCase {
private static final Logger LOGGER = LoggerFactory.getLogger(
Q22284380TestCase.class);
private AtomicBoolean completed = new AtomicBoolean(false);
@Test
public void testName() throws Exception {
final Observable.OnSubscribe<Integer> onSubProduceTwoValues = new Observable.OnSubscribe<Integer>() {
@Override
public void call(final Subscriber<? super Integer> subscriber) {
final Thread thread = new Thread(new Runnable() {
public Integer i = 0;
@Override
public void run() {
final Integer max = 2;
while (i < max) {
subscriber.onNext(i);
i++;
}
subscriber.onCompleted();
}
});
thread.start();
}
};
final Observable<Integer> values = Observable.create(onSubProduceTwoValues);
final Observable<Integer> byTwoMultiplier = values
.flatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer aValue) {
return doubleIt(aValue);
}
});
byTwoMultiplier.subscribe(new Subscriber<Integer>() {
@Override
public void onNext(Integer a) {
LOGGER.info("" + a);
}
@Override
public void onCompleted() {
completed.set(true);
}
@Override
public void onError(Throwable e) {
LOGGER.error(e.getMessage());
}
});
Thread.sleep(1000L);
assertTrue(completed.get());
}
private Observable<Integer> doubleIt(final Integer value) {
return Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(final Subscriber<? super Integer> subscriber) {
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
subscriber.onNext(value * 2);
subscriber.onCompleted();
} catch (Throwable e) {
subscriber.onError(e);
}
}
});
thread.start();
}
});
}
}
拥有值的生成器,它只使用flatMap将doubleIt函数应用于输出。 要做一些不同的事情,你可以阅读zip,如果你想要一个V和A和B的组合。
答案 2 :(得分:0)
我认为这取决于你需要做的A和B之间的构成类型,以及A如何依赖于B。
C对A组成A和B对(A1结合B1,A2结合B2等) - 然后zip
将是你想要的功能。但是,在这种情况下,我想知道当你首先将B转换为A时你是否还不能做那项工作 - 毕竟我假设你将B转换为A元素(在这种情况下,地图将是要走的路) )。
如果您希望为B发出的每个值创建一个新的A(但希望将所有这些组合成一个Observable),那么flatMap
就是您所需要的。
如果您真的首先需要B来创建 A然后再次需要它来合并 A和B,那么您可能希望cache
B来保存你再次计算所有东西的麻烦。
此处还有其他可能感兴趣的功能(例如reduce
或combineLatest
)。也许你可以提供一些关于你想做什么的更多细节?
答案 3 :(得分:0)
如果您正在寻找使异步观察者工作的建议,我建议您快速查看这个问题RxJava Fetching Observables In Parallel。
Ben(RxJava的作者)帮助澄清了我对这个主题的疑虑。
希望这有帮助
阿南德