我有一个由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流程来并行执行任务,并阻止所有任务完成?
答案 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
个)。