如何在启用协程的情况下重试改造接口中的API调用 [英] How to retry API call in retrofit interface with coroutines enabled

查看:68
本文介绍了如何在启用协程的情况下重试改造接口中的API调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,只要API调用出现Internet丢失或未知错误等一般性错误,就需要用重试按钮显示错误UI。当用户按上一次失败的重试时,API应调用并恢复用户流。

迁移协程方法前的API接口:

 interface TodoService {
    @POST("todo/create")
   fun createTodo(@Body request: TodoRequest): Call<TodoResponse>
}

API客户端:

    fun <T> fetch(call: Call<T>, completion: (result: NetworkBoundResource<T>) -> Unit) {
   
    call.enqueue(object : Callback<T> {
        override fun onFailure(call: Call<T>, t: Throwable) {
            // I have the mechanism save call object and completion and show error UI
            // when user press retry fetch(call.clone(), completion
        }

        override fun onResponse(call: Call<T>, response: Response<T>) {

        }
    })
}

在将改造接口迁移到协程挂起方法之前,这不是问题。因为我只需克隆改造后的Call对象(call.clone())并重试API调用,如代码注释中所述。

迁移协程方法后的API接口:

interface TodoService {
   @POST("todo/create")
   suspend fun createTodo(@Body request: TodoRequest): TodoResponse
}

现在如何在没有调用对象的情况下实现相同的功能?

推荐答案

您可以通过将操作保存在协程作业外部来处理重试,例如,在按钮上添加调度。

这里有一个简单的示例,但并不完整:

class ViewModel {

    val context = CoroutineScope(Dispatchers.Main)
    var dispatchRetry: (() -> Unit)? = null

    fun createTodo(requestData: TodoRequest) {
        context.launch() {
            try {
                todoService.createTodo(requestData)
            } catch (t: Throwable) {
                dispatchRetry = { todoService.createTodo(requestData) }
            }
        }
    }

    fun retry() {
        dispatchRetry?.invoke()
    }
}

这篇关于如何在启用协程的情况下重试改造接口中的API调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆