Java RX:并行运行压缩的观测值?
所以我在玩RX(真的很酷),我一直在转换我的api来访问Android中的sqlite数据库,以返回可观测值 因此,我开始尝试解决的一个问题自然是,“如果我想进行3次API调用,得到结果,然后在它们全部完成后进行一些处理,该怎么办?” 这花了我一两个小时,但我最终找到了答案,它很方便地帮了我:Java RX:并行运行压缩的观测值?,java,system.reactive,rx-java,Java,System.reactive,Rx Java,所以我在玩RX(真的很酷),我一直在转换我的api来访问Android中的sqlite数据库,以返回可观测值 因此,我开始尝试解决的一个问题自然是,“如果我想进行3次API调用,得到结果,然后在它们全部完成后进行一些处理,该怎么办?” 这花了我一两个小时,但我最终找到了答案,它很方便地帮了我: Observable<Integer> one = getNumberedObservable(1); Observable<Integer> two = getN
Observable<Integer> one = getNumberedObservable(1);
Observable<Integer> two = getNumberedObservable(2);
Observable<Integer> three = getNumberedObservable(3);
Observable.zip(one, two, three, new Func3<Integer, Integer, Integer, Integer>() {
@Override
public Integer call(Integer arg0, Integer arg1, Integer arg2) {
System.out.println("Zip0: " + arg0);
System.out.println("Zip1: " + arg1);
System.out.println("Zip2: " + arg2);
return arg0 + arg1 + arg2;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer arg0) {
System.out.println("Zipped Result: " + arg0);
}
});
public static Observable<Integer> getNumberedObservable(final int value) {
return Observable.create(new OnSubscribeFunc<Integer>() {
@Override
public Subscription onSubscribe(Observer<? super Integer> observer) {
observer.onNext(value);
observer.onCompleted();
return Subscriptions.empty();
}
});
}
Observable one=GetNumberEndobservable(1);
可观测的2=可观测的GetNumberDebservable(2);
可观测的三个=可观测的(3);
zip(一,二,三,新Func3(){
@凌驾
公共整数调用(整数arg0、整数arg1、整数arg2){
System.out.println(“Zip0:+arg0”);
System.out.println(“Zip1:+arg1”);
System.out.println(“Zip2:+arg2”);
返回arg0+arg1+arg2;
}
}).订阅(新操作1(){
@凌驾
公共无效调用(整数arg0){
System.out.println(“压缩结果:+arg0”);
}
});
公共静态可观测GetNumberEndobservable(最终整数值){
return Observable.create(新建onsubscribeefunc()){
@凌驾
Subscribe上的公共订阅(Observatorzip
会并行运行观察对象,但它也会连续订阅。由于您的GetNumberEndobservable
是在订阅方法中完成的,因此它给人以连续运行的印象,但实际上没有这样的限制
您可以尝试使用一些比其订阅逻辑更有效的长时间运行的观察对象,例如timer
,或者使用subscribeOn
方法异步订阅传递到RxJava中zip的每个流,使用该方法将常规函数转换为将在线程上运行并返回其结果的函数以可观察的方式
我不太懂Java语法,但它看起来像:
public static Integer getNumber(final int value) { return value; }
public static Observable<Integer> getNumberedObservable(final int value) {
return rx.util.functions.toAsync(new Func<Integer,Integer>() {
@Override
public Integer call(Integer value) { return getNumber(value); }
});
};
public静态整数getNumber(最终整数值){返回值;}
公共静态可观测GetNumberEndobservable(最终整数值){
返回rx.util.functions.toAsync(新函数(){
@凌驾
公共整数调用(整数值){return getNumber(value);}
});
};
如果getNumber
真的在访问数据库,那就行了。当你调用getNumberedObservable
时,它返回一个observable,当你订阅它时,它将在一个单独的线程上运行getNumber
。我也在尝试同样的方法,使用zip并行运行多个线程。我结束了打开一个并得到一个答案。基本上,你必须为每个可观察对象订阅一个新线程,因此如果你想使用zip并行运行三个可观察对象,你必须订阅三个单独的线程。啊!我不敢相信我忘记了使用subscribeOn。谢谢你指出这一点。我测试了它,它可以工作。所以现在我很高兴剩下的问题是,如果我想让它们都以串行方式运行,我会只在一个线程上订阅它们,还是有更好的方法将所有可观察对象组合在一起以串行方式运行它们?谢谢!如果你想以串行方式运行它们,你可能使用了错误的API!:)别开玩笑了,你可以这么做,但这很微妙。如果流都是相同的类型,你可以使用concat
链接它们,如果它们都不同,那么你可以创建一个类型来保存n个结果,然后使用concat
和选择将每个流的结果投影到类型中的占位符,然后使用sc一个
来累积单个结果。您也可以只订阅前一个未完成的流中的每个连续流。您还可以使用selectMany
将前一个流的结果投影到下一个流的查询中。如果将一个流的结果传递到下一个流中,则此操作非常有效。此外,在s上订阅所有流单线程不能保证工作-subscribe方法在操作员完成之前返回是很常见的。如果我可能会问,为什么要等到这三个线程都完成后再进行处理?@ScottSEA当然可以,所以set假设我有一个屏幕,需要SQLite中的3个不同元素来正确绘制,或者3个不同的网络片段信息。在开始绘制屏幕之前,我想确保我已经准备好了所有内容。因此,你不是在等待序列完成,而是在等待每个序列都有一个值吗?@ScottSEA我设置api的方式是,所有内容都只返回一个对象,然后完成。如果你觉得有更好的方法设置说到这里,我洗耳恭听。我对RX很陌生,很想听听你说什么。@ScottSEA即使我退回了多个项目,我也只发送一个项目列表,而不是多个onNext电话。