Так что в настоящее время я объединяю вызовы API вместе с помощью flatMap, и это хорошо работает для моих случаев использования.Если один из моих вызовов возвращает ошибочный код ответа, то я передаю сингл с ошибкой, который содержит метод throwable с сообщением, в котором говорится, какой вызов не выполнен, и он продолжает идти.Вот как я это делаю сейчас:
dataManager.apiCall1(dataManager.sessionId!!)
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.flatMap{apiCall1Response ->
if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
// First api call was successful, execute api call 2.
return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
} else {
// First api call failed
return@flatMap Single.error<Throwable>(Throwable("First api call failed."))
}
}.flatMap{apiCall2Response ->
if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
// Second api call was successful, execute api call 3.
return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
} else if (apiCall2Response is Throwable) {
// Api Call 1 Failed.
return@flatMap Single.error<Throwable>(apiCall2Response)
} else {
// Second api call failed
return@flatMap Single.error<Throwable>(Throwable("Second api call failed."))
}
}.subscribe({apiCall3Response ->
if (apiCall3Response is Response<*> && apiCall3Response.body() != null) {
// Success!
navigator?.successful(response)
} else if (apiCall3Response is Throwable) {
// Something failed from before.
navigator?.handleError(apiCall3Response)
} else {
// Third api call failed, handle error
navigator!!.handleError(Throwable("Api call 3 failed."))
}
}, {throwable ->
navigator!!.handleError(throwable)
})
Что ж, теперь я понимаю, что мне нужно сделать другой вызов API, если мой первый вызов API успешен и любой из моих других вызовов не удался.Это последовательность вызовов для входа пользователя в систему, если вход в систему выполнен успешно, но следующий вызов не удался, нам нужно вызвать конечную точку выхода API.Я знаю, что создавать метод сингла внутри метода subscribe () - плохая практика, поэтому я не хочу этого делать.Я бы предпочел пропустить вызов выхода из системы, но проблема в том, что нет способа узнать, какой вызов API возвращается в методе подписки, так как и выход из системы, и apiCall3 возвращают пустые тела.Я также хотел бы вызвать конечную точку выхода из системы в случае сбоя apiCall3, но не уверен, возможно ли это.Вот что я пытаюсь сделать:
dataManager.apiCall1(dataManager.sessionId!!)
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.flatMap{apiCall1Response ->
if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
// First api call was successful, execute api call 2.
return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
} else {
// First api call failed
return@flatMap Single.error<Throwable>(Throwable("First api call failed."))
}
}.flatMap{apiCall2Response ->
if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
// Second api call was successful, execute api call 3.
return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
} else if (apiCall2Response is Throwable) {
// Api Call 1 Failed.
return@flatMap Single.error<Throwable>(apiCall2Response)
} else {
// Second api call failed, logout
return@flatMap dataManager.logoutApiCall()
}
}.subscribe({apiCall3OrLogoutResponse ->
// I would like to be able to determine which call this response is from. That is the question.
if (apiCall3OrLogoutResponse is Response<*> && apiCall3OrLogoutResponse.body() != null) {
// Success!
navigator?.successful(response)
} else if (apiCall3OrLogoutResponse is Throwable) {
// Something failed from before.
navigator?.handleError(apiCall3OrLogoutResponse)
} else {
// Third api call or logout call failed, handle error
if (apiCall3OrLogoutResponse is ApiCall3) {
// Api Call 3 failed.
// Somehow call logout api endpoint
} else if (apiCall3OrLogoutResponse is LogoutCall {
// Logout call failed.
navigator?.handleError(Throwable("Logout failed."))
}
}
}, {throwable ->
navigator!!.handleError(throwable)
})
Есть ли лучший способ сделать это?В моих сценариях использования я делаю три последовательных вызова API, в случае сбоя первого из них отправляю подписчику подбрасываемый объект, если первый выполняется успешно и после этого происходит сбой, сделайте еще один вызов API.