Java RX,为什么此行被调用两次而这两行从未被调用

时间:2019-04-11 13:07:14

标签: java rx-java reactive-programming

我是Java Rx的新手,我不知道这是否是一个有效的问题。

我有功能

    public Single<PayResponse> pay(PayRequest apiRequest) {

                return client.initiatePayment(apiRequest)
                        .doOnSuccess(initiatePaymentResponse -> {
                            System.out.println("first");
                            client.confirmPayment(initiatePaymentResponse.getPaymentId())
                                    .doOnSuccess(confirmPaymentResponse -> {System.out.println("second");doConfirmationLogic(confirmPaymentResponse ))}
                                    .doOnError(ex -> {System.out.println("thirs");ex.printStackTrace();logError(ex);});
                        })

                        .doOnError(ex -> {ex.printStackTrace();logError(ex);});
            } 

执行此方法后,我发现 first 被打印了两次,但 second third 已打印

对我来说这是奇怪的行为,因为我希望找到 first second third < / strong>。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

为了开始接收来自可观察对象(如Single<T>)的发射值,您必须先subscribe()

您可能只订阅了Single返回的pay两次,这就是为什么您看到first被打印两次的原因。在您显示的代码中,我可以看到那里没有订阅任何可观察的东西,因此事后没有任何反应。

如果要链接可观察变量,最常见的选择是使用flatMap运算符(还有其他选项)。

在您的情况下,它看起来类似于:

public Single<PayResponse> pay(PayRequest apiRequest) {

    return client.initiatePayment(apiRequest)
                .flatMap(initiatePaymentResponse -> {
                        System.out.println("first");
                        return client.confirmPayment(initiatePaymentResponse.getPaymentId();
                })
                .flatMap(confirmPaymentResponse -> {
                        System.out.println("second");
                        return doConfirmationLogic(confirmPaymentResponse);
                })
               .doOnSuccess(confirmationLogicResponse -> System.out.println("third"))
               .doOnError(ex -> {
                        ex.printStackTrace();
                        logError(ex);
                });
} 

然后,您订阅pay返回的单曲,如下所示:

...
pay(apiRequest)
     .subscribe(onSuccesValue -> {
             // The whole chain was successful and this is the value returned 
             // by the last observable in the chain (doConfirmationLogic in your case)
      }, onError {
             // There was an error at some point during the chain
      }
...

我假设所有方法initiatePaymentconfirmPaymentdoConfirmationLogic返回Singles,而doConfirmationLogic最终返回Single<PayResponse>。如果不是这种情况,您将需要进行一些小的更改,但是您已经获得了可观察的链式工作原理的大致概念。