sha*_*l.k 26 android async-await kotlin retrofit2 kotlin-coroutines
我正在使用kotlin coroutines进行网络请求,使用扩展方法在这样的改造中调用类
public suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>?, response: Response<T?>) {
if (response.isSuccessful) {
val body = response.body()
if (body == null) {
continuation.resumeWithException(
NullPointerException("Response body is null")
)
} else {
continuation.resume(body)
}
} else {
continuation.resumeWithException(HttpException(response))
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
// Don't bother with resuming the continuation if it is already cancelled.
if (continuation.isCancelled) return
continuation.resumeWithException(t)
}
})
registerOnCompletion(continuation)
}
}
Run Code Online (Sandbox Code Playgroud)
然后从呼叫方我使用这样的上述方法
private fun getArticles() = launch(UI) {
loading.value = true
try {
val networkResult = api.getArticle().await()
articles.value = networkResult
}catch (e: Throwable){
e.printStackTrace()
message.value = e.message
}finally {
loading.value = false
}
}
Run Code Online (Sandbox Code Playgroud)
我希望在某些情况下指数重试此api调用即(IOException)如何实现它?
Rom*_*rov 86
我建议为重试逻辑编写一个帮助程序高阶函数.您可以使用以下实现来开始:
suspend fun <T> retryIO(
times: Int = Int.MAX_VALUE,
initialDelay: Long = 100, // 0.1 second
maxDelay: Long = 1000, // 1 second
factor: Double = 2.0,
block: suspend () -> T): T
{
var currentDelay = initialDelay
repeat(times - 1) {
try {
return block()
} catch (e: IOException) {
// you can log an error here and/or make a more finer-grained
// analysis of the cause to see if retry is needed
}
delay(currentDelay)
currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
}
return block() // last attempt
}
Run Code Online (Sandbox Code Playgroud)
使用此功能非常简单:
val networkResult = retryIO { api.getArticle().await() }
Run Code Online (Sandbox Code Playgroud)
您可以根据具体情况更改重试参数,例如:
val networkResult = retryIO(times = 3) { api.doSomething().await() }
Run Code Online (Sandbox Code Playgroud)
您还可以完全更改实现retryIO以满足应用程序的需要.例如,您可以对所有重试参数进行硬编码,摆脱重试次数的限制,更改默认值等.
| 归档时间: |
|
| 查看次数: |
5619 次 |
| 最近记录: |