使用RxJava异步调用多个同步任务

时间:2016-02-25 12:14:56

标签: java rx-java

我有一个由Futures代表的异步任务在一个单独的线程池中执行,我想用RxJava加入它。使用Java 5构造的“旧”方式就是这样(省略收集结果):

final Future<Response> future1 = wsClient.callAsync();
final Future<Response> future2 = wsClient.callAsync();
final Future<Response> future3 = wsClient.callAsync();
final Future<Response> future4 = wsClient.callAsync();

future1.get();
future2.get();
future3.get();
future4.get();

这将阻止我的当前线程,直到所有期货都完成,但是呼叫将是并行的,整个操作只会花费相当于最长呼叫的时间。

我想使用RxJava做同样的事情,但在谈到如何正确建模时,我有点像菜鸟。

我尝试了以下内容,似乎有效:

Observable.from(Arrays.asList(1,2,3,4))
            .flatMap(n -> Observable.from(wsClient.callAsync(), Schedulers.io()))
            .toList()
            .toBlocking()
            .single();

这种方法的问题在于我引入了Schedulers.io线程池,这会导致不必要的线程切换,因为我已经阻塞了当前线程(使用toBlocking())。 有没有什么方法可以模拟Rx流程来并行执行任务,并阻止所有任务完成?

1 个答案:

答案 0 :(得分:1)

您应该使用zip功能。 例如:

Observable.zip(
        Observable.from(wsClient.callAsync(), Schedulers.io()),
        Observable.from(wsClient.callAsync(), Schedulers.io()),
        Observable.from(wsClient.callAsync(), Schedulers.io()),
        Observable.from(wsClient.callAsync(), Schedulers.io()),
        (response1, response2, response3, response4) -> {
            // This is a zipping function...
            // You'll end up here when you've got all responses
            // Do what you want with them and return a combined result
            // ...
            return null; //combined result instead of null
        })
        .subscribe(combinedResult -> {
            // Use the combined result
        });

Observable.zip也可以与Iterable一起使用,这样您就可以将Observable.from(wsClient.callAsync(), Schedulers.io());包围一个(返回4个)。