RxJava如何从CompletableFuture <Long>

时间:2019-12-02 12:46:02

标签: rx-java2

提供了一个存储库类,该存储库类返回一个:

Single<SomeObject> find()

和一个返回Float的CompletableFuture:

CompletableFuture<Long> completableFuture

我想先调用存储库方法,然后根据结果,我需要调用completableFuture。这是我的代码:

repository.find()
          .flatMap(s -> {
              CompletableFuture<Long> completableFuture = serviceReturningCompletableFuture;

              return Single.fromFuture(completableFuture);

          }).subscribe(System.out::println)

这里的问题是Single.fromFuture将被阻止,因此无法使用。

为了解决此问题,我尝试了以下操作:

repository.find()
          .map(s -> {
              CompletableFuture<Long> completableFuture = new CompletableFuture<>();

              return Flowable.fromFuture(completableFuture);
          }).subscribe(System.out::println)

这可以正常工作而不会阻塞,订阅函数将打印以下内容,而不是CompletableFuture返回的数字

io.reactivex.internal.operators.flowable.FlowableFromFuture@62ce978e

我还尝试使用无阻塞转换器从net.javacrumbs.future-converter:future-converter-rxjava-java8:1.2.0中进行单曲

repository.find()
          .map(s -> {
              CompletableFuture<Long> completableFuture = new CompletableFuture<>();

              return toSingle(completableFuture);
          }).subscribe(System.out::println)

但是,这将导致几乎相同的输出:net.javacrumbs.futureconverter.rxjavacommon.RxJavaFutureUtils$ValueSourceBackedSingle@3f1eebb8

我想念什么?

1 个答案:

答案 0 :(得分:0)

稍后再摆弄这个辅助方法:

public static <T> Single<T> toSingle(CompletableFuture<T> future) {
    return Single.create(subscriber ->
            future.whenComplete((result, error) -> {
                if (error != null) {
                    subscriber.onError(error);
                } else {
                    subscriber.onSuccess(result);
                }
            }));
}

似乎可以解决问题:

repository.find()
          .flatMap(s -> {
              CompletableFuture<Long> completableFuture = serviceReturningCompletableFuture;

              return toSingle(completableFuture);

          }).subscribe(System.out::println)

就像@akarnokd在评论中指出的那样,有这个库: https://github.com/akarnokd/RxJavaJdk8Interop#completionstage-to-rxjava的运作方式大致相同:

repository.find()
          .flatMap(s -> {
              CompletableFuture<Long> completableFuture = serviceReturningCompletableFuture;

              return SingleInterop.fromFuture(completableFuture);

          }).subscribe(System.out::println)