同时查询多个ID,然后合并到一个Observable中

时间:2016-08-08 04:30:50

标签: java rx-java

我有一个需要从远程API查询的ID列表。我希望从API并行查询实体(同时),并维护列表中的ID顺序。

如何使用Observables实现这一目标?

Observable<String> strings = Observable.from(Arrays.asList(5, 4, 7, 2, 1)
                .stream()
                .map(Main::retrieve)
                .collect(Collectors.toList()))
                .flatMap(o -> o);

使用上面的代码段并不能保证订单。

2 个答案:

答案 0 :(得分:1)

我使用concatMapEager代替flatMap

实现了此行为

答案 1 :(得分:0)

我不确定在Stream内部使用Java 8 Observable.from(...) API进行收集是一个好主意,因为它将两个API与他们自己的并发意见混合在一起。

相反,我会调用Main::retrieve来回复Observable(可能使用Observable.fromCallable),我会在subscribeOn(Schedulers.io())内调用flatMap运算符1}}。

Schedulers.io()使用带有不断增长的线程池的RxJava调度程序,用于长时间运行但CPU轻量级的任务(通常是IO)。

如果订购**并且*并行化都很重要,那么可以使用flatMap代替concatMapEagerconcatMap将通过等待第一个内部Observable在触发第二个之前完成维护顺序,等等...... 另一方面,concatMapEager触发所有内部Observable,然后缓冲那些无序返回的Observable,以便在可能的情况下尽快重放它们。

这是一种最小的方法:触发[ABC]并以[ACB]顺序接收意味着可以立即发出“A”(正确的顺序),C被缓冲直到B到达,然后从缓冲区刷新并发出。

所以代码看起来像:

Observable<String> strings = Observable.from(Arrays.asList(5, 4, 7, 2, 1))
    //be efficient / parallel friendly but still retain order
    .concatMapEager(i -> 
        //Main's method has been converted to return an Observable
        retrieve(i)
        //retrieve will be executed in its own IO thread, so in parallel
        .subscribeOn(Schedulers.io())
    );