Java RX, почему эта строка вызывается дважды, а эти 2 строки никогда не называются - PullRequest
1 голос
/ 11 апреля 2019

Я новичок в 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.

Есть идеи?

1 Ответ

1 голос
/ 11 апреля 2019

Чтобы начать получать испускаемые значения из наблюдаемой (например, 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
      }
...

Я предполагаю, что все методы initiatePayment, confirmPayment, doConfirmationLogic возвращают Singles и что doConfirmationLogic в конечном итоге возвращает Single<PayResponse>. Если это не так, вам нужно будет внести небольшие изменения, но вы получите общее представление о том, как работают цепочки наблюдаемых.

...