等待多个异步调用在RxJava中完成

时间:2016-09-15 18:04:36

标签: java asynchronous rx-java reactive-programming

我的情景非常简单,但我似乎无法在任何地方找到它。

我有一组要迭代的元素,每一个都调用异步函数,然后等待所有这些元素完成(这又以异步方式发生,在函数的逻辑中实现) 。我对RxJava相对较新,并且通过将回调传递给函数并在最后等待,在NodeJS中很容易做到这一点。 这是我需要的伪代码(元素的迭代器不需要同步也不需要有序):

for(line in lines){
 callAsyncFunction(line);
}
WAIT FOR ALL OF THEM TO FINISH

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

使用Rx:

Observable
.from(lines)
.flatMap(line -> callAsyncFunctionThatReturnsObservable(line).subscribeOn(Schedulers.io())
.ignoreElements();

此时,根据您的目的,您可以使用.switchIfEmpty(...)订阅另一个可观察对象。

答案 1 :(得分:1)

技术上如果你考虑一下,你需要做的是从你的所有元素创建一个Observable,然后zip them together继续你的流的执行。

伪代码会给你这样的东西:

List<Observable<?>> observables = new ArrayList<>();
for(line in lines){
   observables.add(Observable.fromCallable(callAsyncFunction(line));
}
Observable.zip(observables, new Function<...>() { ... }); // kinda like Promise.all()

Observable.from()可以将迭代中的每个元素作为对象流公开,从而消除对循环的需求,这一点也就不足为奇了。因此,您可以使用onCompleted()创建一个新的Observable,在异步操作完成时调用Observable.fromCallable()。之后,您可以将这些新Observable收集到列表中等待。

Observable.from(lines)
   .flatMap(new Func1<String, Observable<?>>() {
        @Override
        public Observable<?> call(String line) {
            return Observable.fromCallable(callAsyncFunction(line)); // returns Callable
        }
    }).toList()
      .map(new Func1<List<Object>, Object>() {
        @Override
        public Object call(List<Object> ignored) {
            // do something;
        }
    });

我的答案的后半部分主要基于this answer

答案 2 :(得分:0)

将&#34;项的Iterable转换为计算&#34;使用defer,然后使用zip对Observables进行可观察的可观察对象。

更难的部分将是#34;等待他们全部完成&#34;。正如您可能已经猜到的那样,Reactive Extensions是关于&#34;反应&#34;东西,而不是&#34;等待事情发生。&#34;您可以subscribe到observable,它将发出单个项目,然后在每个observable只有一个项目时完成。该订户可以在等待之后执行您通常会执行的任何操作;这允许您返回并让代码执行其操作而不会阻塞它。

相关问题