#java #rx-java #reactive-programming
#java #rx-java #реактивное программирование
Вопрос:
Я новичок в 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. Источники, когда они не подписаны, ничего не делают. Вы должны использовать
flatMap
вместоdoOnSuccess
. Возможно, вы получаетеfirst
дважды, потому что вы подписываетесь на результатpay()
дважды.
Ответ №1:
Чтобы начать получать передаваемые значения из наблюдаемого (например, a 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
в конечном итоге возвращает a Single<PayResponse>
. Если это не так, вам нужно будет внести некоторые небольшие изменения, но вы получите общее представление о том, как работают наблюдаемые цепочки.