RxJava顺序异步任务的顺序结果

时间:2016-01-27 06:17:59

标签: rx-java

我有必须并行处理的对象流(它是长时间运行的任务),但同时我必须保留结果序列。我试图使用RxJava,但找不到任何好的解决方案。

基本思想,就是将每个对象转化为未来的功能然后按顺序调用每个未来。如果将来完成Exception,我需要重试它,直到它实际上已成功完成。

public class RxTest {

    private static CompletableFuture<String> futureFunction(int i) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (ThreadLocalRandom.current().nextInt(1, 100) < 10) {
                throw new RuntimeException("failed.. sorry");
            }

            return Thread.currentThread().getName() + " " + String.valueOf(i);
        });
    }

    public static void main(String[] args) throws InterruptedException {

        Observable.range(1, 100)
                .flatMap(i ->
                        Observable.just(i).map(RxTest::futureFunction).flatMap(Observable::from).retry()
                )

                .observeOn(Schedulers.from(Executors.newSingleThreadExecutor()))

                .subscribe(Subscribers.create((x) -> {
                    System.out.println(Thread.currentThread().getName() + " " + x);
                }));

    }
}

在这个例子中,我收到顺序输出

pool-1-thread-1 ForkJoinPool.commonPool-worker-9 1
pool-1-thread-1 ForkJoinPool.commonPool-worker-9 2
pool-1-thread-1 ForkJoinPool.commonPool-worker-9 3
pool-1-thread-1 ForkJoinPool.commonPool-worker-9 4
pool-1-thread-1 ForkJoinPool.commonPool-worker-9 5
pool-1-thread-1 ForkJoinPool.commonPool-worker-9 6

但每个未来都是在前一个完成之后创建和调用的,而不是像我预期的那样并行。

我正在玩observeOn()subscribeOn(),没有任何效果。

1 个答案:

答案 0 :(得分:1)

您可以使用concatMapEagerconcatEager运行来源,但在发出时保留项目顺序:

Observable.range(1, 100)
.concatMapEager(v -> 
    Observable.fromCallable(() -> { ... })
    .subscribeOn(Schedulers.computation())
    .retry()
)
.subscribe(...)