[英]Android RxJava2 - How to make api call when error is thrown?
因此,我目前正在使用flatMap將API調用鏈接在一起,並且在我的用例中效果很好。 如果我的一個呼叫返回失敗的響應代碼,那么我將傳遞一個錯誤單,其中包含一個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()方法中創建另一個單一的方法是不好的做法,所以我不想這樣做。 我寧願通過注銷調用,但問題是由於注銷和apiCall3都返回空主體,因此無法知道在subscribe方法中返回哪個api調用。 如果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調用。
我通過拋出自定義異常而不是向下傳遞Single.error並在flatMapCompletable中而不是在訂閱中檢查了我的最終調用來解決了這一問題。 然后,如果異常不是登錄異常,則在doOnError中調用注銷端點。
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
throw ApiCall1Exception("Api Call 1 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 {
// Second api call failed
throw Throwable("Api call 2 failed.")
}
}.flatMapCompletable{apiCall3Response ->
if (apiCall3Response.body() != null) {
// All api calls were successful!
Completable.complete()
} else {
// Third api call failed.
throw Throwable("Api call 3 failed.")
}
}.doOnError{throwable ->
if (throwable !is ApiCall1Exception) {
// Api call 1 was successful, but something else failed, call logout endpoint.
dataManager.logout()
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
}
}.subscribe({
// Success!
navigator?.success()
}, {throwable ->
// Something failed!
navigator?.handleError(throwable)
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.