Java 合并一个可观察的列表,等待所有操作完成

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等等。。。但是,如果我正确理解文档,我就无法处理我将要建立的列表,因为它们似

TL;DR 如何将
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