如何展平Flowable <listenablefuture <list <t>&gt;&gt;流动<t>异步?

时间:2016-10-25 14:24:30

标签: rx-java

我正在使用RxJava 2.0.0-RC4。

在我的申请表中,我收到Flowable<ListenableFuture<List<Integer>>。 (ListenableFuture来自番石榴。)

如何将此流畅的内容展平为Flowable<Integer>

我试过了:

Flowable<ListenableFuture<List<Integer>>> futures = ...
Flowable<Integer> ints = futures.flatMap(future -> Flowable.fromIterable(future.get()));

但这涉及到阻止通话(Future.get())。理想情况下,我想以完全非阻塞的方式创建可流动的,以便在底层期货完成时它会立即发出项目(我不需要保留生成的可流动元素的元素排序)

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

@Test
public void name() throws Exception {
    ListenableFuture<List<Integer>> listListenableFuture = Futures.immediateFuture(Arrays.asList(1, 2, 3));

    Flowable<List<Integer>> futures = Flowable.fromCallable(() -> listListenableFuture.get());

    Flowable<Integer> integerFlowable = futures
            .flatMap(integers -> Flowable.fromIterable(integers));

    TestSubscriber<Integer> test = integerFlowable.test();

    test.assertValues(1, 2, 3);
}

如果引入subscribeOn / observeOn,测试将失败。我建议通过挂钩生命周期事件来包装ListenableFuture。

包装看起来像这样:

    @Test
public void name() throws Exception {
    ListenableFuture<List<Integer>> listListenableFuture = Futures.immediateFuture(Arrays.asList(1, 2, 3));

    Flowable<List<Integer>> listFlowable = Flowable.create(e -> {
        if (e.isCancelled()) {
            return;
        }

        try {
            FutureCallback<List<Integer>> futureCallback = new FutureCallback<List<Integer>>() {
                @Override
                public void onSuccess(List<Integer> result) {
                    if (!e.isCancelled()) {
                        printCurrentThread("inOnSuccess");

                        e.onNext(result);
                        e.onComplete();
                    }
                }

                @Override
                public void onFailure(Throwable t) {
                    if (!e.isCancelled()) {
                        e.onError(t);
                    }
                }
            };

            Futures.addCallback(listListenableFuture, futureCallback);

            e.setDisposable(Disposables.fromFuture(listListenableFuture, true));

        } catch (Exception ex) {
            e.onError(ex);
        }

    }, BackpressureStrategy.BUFFER);

    Flowable<Integer> integerFlowable = listFlowable
            .subscribeOn(Schedulers.computation())
            .observeOn(Schedulers.newThread())
            .doOnNext(integers -> printCurrentThread("afterObserveOn"))
            .flatMap(Flowable::fromIterable);

    TestSubscriber<Integer> test = integerFlowable.test();

    Thread.sleep(200);

    test.assertResult(1, 2, 3);
}

private void printCurrentThread(String additional) {
    System.out.println(additional + "_" + Thread.currentThread());
}