Java 合并一个可观察的列表,等待所有操作完成
TL;DR 如何将Java 合并一个可观察的列表,等待所有操作完成,java,rx-java,reactive-programming,rx-android,Java,Rx Java,Reactive Programming,Rx Android,TL;DR 如何将Task.whalll(List)转换为RxJava 我现有的代码使用bolt构建异步任务列表,并在执行其他步骤之前等待所有这些任务完成。本质上,它建立一个列表,并返回一个任务,当列表中的所有任务都完成时,该任务将根据 我希望用RxJava替换bolt,我假设这种方法可以建立一个异步任务列表(大小事先不知道),并将它们全部包装到一个可观察的中,但我不知道如何实现 我试过看merge,zip,concat等等。。。但是,如果我正确理解文档,我就无法处理我将要建立的列表,因为它们似
Task.whalll(List)
转换为RxJava
我现有的代码使用bolt构建异步任务列表,并在执行其他步骤之前等待所有这些任务完成。本质上,它建立一个列表
,并返回一个任务
,当列表中的所有任务都完成时,该任务将根据
我希望用RxJava
替换bolt
,我假设这种方法可以建立一个异步任务列表(大小事先不知道),并将它们全部包装到一个可观察的中,但我不知道如何实现
我试过看merge
,zip
,concat
等等。。。但是,如果我正确理解文档,我就无法处理我将要建立的列表
,因为它们似乎一次只处理两个可观察对象
我正在努力学习RxJava
,而且还是一个新手,所以如果这是一个明显的问题或者在文档中有解释,请原谅我;我试过搜索。任何帮助都将不胜感激。您可能看到了使用2个可观察对象的zip
操作符
还有静态方法Observable.zip
。它有一种对您有用的形式:
zip(java.lang.Iterable<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)
zip(java.lang.Iterable>ws,FuncN听起来你在寻找新的
有几种不同的使用方法,让我们看一个例子。假设我们有几种不同类型的简单观测值:
Observable<Integer> obs1 = Observable.just(1);
Observable<String> obs2 = Observable.just("Blah");
Observable<Boolean> obs3 = Observable.just(true);
请注意,在zip函数中,参数具有与正在压缩的可观察对象的类型相对应的具体类型
也可以直接压缩观察列表:
List<Observable<?>> obsList = Arrays.asList(obs1, obs2, obs3);
Observable.zip(obsList, (i) -> i[0] + " " + i[1] + " " + i[2])
.subscribe(str -> System.out.println(str));
然后1,诸如此类,True
和2,Hello,True
将是传递到zip函数中的唯一项目。由于其他观察对象已完成,因此项目3
将永远不会被压缩。如果您有动态任务组合,您可以使用flatMap
Observable.zip(obs1, obs2, obs3, (Integer i, String s, Boolean b) -> i + " " + s + " " + b)
.subscribe(str -> System.out.println(str));
Observable<Integer> obs1 = Observable.from(new Integer[]{1,2,3}); //Emits three items
Observable<String> obs2 = Observable.from(new String[]{"Blah","Hello"}); //Emits two items
Observable<Boolean> obs3 = Observable.from(new Boolean[]{true,true}); //Emits two items
public Observable<Boolean> whenAll(List<Observable<Boolean>> tasks) {
return Observable.from(tasks)
//execute in parallel
.flatMap(task -> task.observeOn(Schedulers.computation()))
//wait, until all task are executed
//be aware, all your observable should emit onComplemete event
//otherwise you will wait forever
.toList()
//could implement more intelligent logic. eg. check that everything is successful
.map(results -> true);
}
公共可观察时间(列出任务){
可观察的返回。来自(任务)
//并行执行
.flatMap(任务->任务.observeOn(Schedulers.computation())
//等待,直到所有任务都执行完毕
//请注意,您的所有可观察对象都应发出onComplemete事件
//否则你将永远等待
托利斯先生()
//可以实现更智能的逻辑。例如,检查一切是否成功
.map(结果->真);
}
注意:我真的不知道您对错误处理的要求。例如,如果只有一个任务失败,该怎么办。我认为您应该验证这个场景。我正在用Kotlin编写一些带有JavaRx Observables和RxKotlin的计算重磅代码。我想观察一个要完成的Observables列表,同时给我一个更新h进度和最新结果。最后它返回最佳计算结果。额外的要求是并行运行Observables以使用所有cpu内核。我最终得到了以下解决方案:
@Volatile var results: MutableList<CalculationResult> = mutableListOf()
fun doALotOfCalculations(listOfCalculations: List<Calculation>): Observable<Pair<String, CalculationResult>> {
return Observable.create { subscriber ->
Observable.concatEager(listOfCalculations.map { calculation: Calculation ->
doCalculation(calculation).subscribeOn(Schedulers.computation()) // function doCalculation returns an Observable with only one result
}).subscribeBy(
onNext = {
results.add(it)
subscriber.onNext(Pair("A calculation is ready", it))
},
onComplete = {
subscriber.onNext(Pair("Finished: ${results.size}", findBestCalculation(results))
subscriber.onComplete()
},
onError = {
subscriber.onError(it)
}
)
}
}
@Volatile-var-results:MutableList=mutableListOf()
计算的乐趣(计算列表:列表):可观察{
return Observable.create{subscriber->
Observable.concatEager(listOfCalculations.map{calculation:calculation->
doccalculation(calculation).subscribeOn(Schedulers.computation())//函数doccalculation返回一个只有一个结果的可观察值
}).订阅人(
onNext={
结果。添加(it)
subscriber.onNext(Pair(“计算就绪”,it))
},
未完成={
subscriber.onNext(对(“Finished:${results.size}”),findBestCalculation(results))
subscriber.onComplete()
},
onError={
订户。OneError(it)
}
)
}
}
与Kotlin
Observable.zip(obs1, obs2, BiFunction { t1 : Boolean, t2:Boolean ->
})
设置函数参数的类型很重要,否则会出现编译错误
最后一个参数类型随参数数量的变化而变化:
2的双功能
功能3对3
函数4为4
在提出的建议中,实际上将可观察到的结果相互结合,这可能是想要的,也可能不是想要的,但问题中没有提出。在问题中,想要的只是逐个或并行地执行每个操作(未指定,但链接螺栓示例是关于并行执行的)。此外,当任何可观察对象完成时,zip()将立即完成,因此这违反了要求
对于平行执行观察值,flatMap()可以,但更直接。请注意,合并将在任何观察值出现错误时退出,如果您宁愿推迟退出,直到所有观察值都完成,您应该查看
对于一个接一个,我认为应该使用它。它的javadoc状态如下:
Observable.zip(obs1, obs2, obs3, (Integer i, String s, Boolean b) -> i + " " + s + " " + b)
.subscribe(str -> System.out.println(str));
Observable<Integer> obs1 = Observable.from(new Integer[]{1,2,3}); //Emits three items
Observable<String> obs2 = Observable.from(new String[]{"Blah","Hello"}); //Emits two items
Observable<Boolean> obs3 = Observable.from(new Boolean[]{true,true}); //Emits two items
public Observable<Boolean> whenAll(List<Observable<Boolean>> tasks) {
return Observable.from(tasks)
//execute in parallel
.flatMap(task -> task.observeOn(Schedulers.computation()))
//wait, until all task are executed
//be aware, all your observable should emit onComplemete event
//otherwise you will wait forever
.toList()
//could implement more intelligent logic. eg. check that everything is successful
.map(results -> true);
}
concat(java.lang.Iterable>序列)
将一组可观察对象一个接一个地展平为一个可观察对象,而不交错
如果你不想并行执行,这听起来像是你想要的
此外,如果您只对任务的完成感兴趣,而不是返回值,那么您可能应该查看而不是
TLDR:对于任务的逐个执行和完成时的oncompletion事件,我认为Completable.concat()最适合。对于并行执行,Completable.merge()或Completable.mergeDelayError()最适合听起来像是解决方案。前一个会在任何完整表上出现任何错误时立即停止,后一个会执行所有这些错误,即使其中一个有错误,然后才报告错误。我有类似的问题,我需要fetc