【发布时间】:2019-06-22 22:44:45
【问题描述】:
所以我目前正在使用 flatMap 将 API 调用链接在一起,它在我的用例中运行良好。如果我的一个调用返回一个失败的响应代码,那么我将传递一个错误单,其中包含一个可抛出的消息,该消息说明哪个调用失败并且它继续进行。这是我现在的做法:
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 调用,如果第一个失败,则向订阅者发送一个 throwable,如果第一个成功并且之后任何失败,则进行另一个 api 调用。
【问题讨论】:
标签: android mvvm kotlin rx-java2 rx-android