【问题标题】:Retrofit 2 with coroutine call adapter factory cancel request使用协程调用适配器工厂取消请求的改造 2
【发布时间】:2018-07-09 19:08:02
【问题描述】:

我正在尝试使用带有协程调用适配器工厂的retrofit2 在我的android 应用程序中实现动态搜索功能。当用户键入关键字并且关键字长度有效时,应用程序向服务器发出请求。在单个请求中,我可以像下面这样请求

launch(UI) {
        try {
            val user = Client.provideService().getUsers()
            //do sometihng with user.await()
        }catch (e: Exception){
            //Handle exception
        }
    }

但是如果我想取消之前的每个请求并在用户更改可编辑项时发出新请求怎么办?我搜索了很多例子,但我找不到任何有用的东西。感谢您的帮助。

【问题讨论】:

    标签: android kotlin retrofit2 deferred kotlinx.coroutines


    【解决方案1】:

    如果您想取消协程,可以按照guide 中的说明进行操作。您需要在从launch 返回的Job 上调用cancel

    val job = launch {
       //...
    }
    
    job.cancel() // cancels the job 
    

    但重要的是要知道协程取消是合作的,即在协程中执行的块需要对协程外部的取消作出反应。您可以使用isActive 检查状态,如here 所述。

    对于您的示例,您必须能够在 isActive 变为 true 时取消 Client.provideService().getUsers() 的计算。

    【讨论】:

    • 显式检查isActive 仅对于几乎从不暂停的循环是必要的。在 OP 的情况下,协程将被挂起,直到响应到来,如果它在该状态下被取消,它将不会恢复。
    • 这不起作用。调用 await 后 Deferred.cancel 不起作用。我需要另一个好的设计。
    • “之后”是什么意思?你不能指望取消来自你调用await的同一个协程的调用,这是矛盾的。
    • 在 viewMode 类中有一个字段, val data = MutableLiveData() 当响应返回时,我们将新用户设置为数据。假设用户使用关键字“jo”请求,然后响应返回并 viewmodel 设置数据值。但是用户继续输入并输入关键字“joh”,那么如果视图模型不取消先前的请求数据将是错误的,因为“jo”请求响应。在带有 call 的 retrofit2 或带有一次性的 rxjava2 中,我们可以调用 call.cancel 或 Disposable.dispose 并使用 new 关键字再次请求。我们如何使用协程处理这种情况。我希望我足够清楚。
    猜你喜欢
    • 1970-01-01
    • 2021-08-16
    • 2021-05-21
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多