【问题标题】:Conceptual question regarding suspend and Deferred关于暂停和延迟的概念问题
【发布时间】:2019-09-11 04:21:38
【问题描述】:

我有一个关于何时使用暂停和何时不使用的问题。我的 APIRepo 类有这样的功能 -

override suspend fun retrieveDataFromRemote(): MyResult {
        if (utility.checkDeviceInternetConnection()) {
            try {
                val result = remoteInterface.getData().await()
                return ...
            } catch (t: Throwable) {
                return ...
            }
        } else {
            return ...
        }
    }

我的远程接口代码如下所示 -

@GET("/data/mydata")
fun getData(): Deferred<Response<MyModel>>

如您所见,我的RemoteInterface 没有suspend 关键字并返回Deferred。这工作得很好。但是当我将suspend 关键字添加到getData() 时,我没有得到API 响应。为什么会这样?和Deferred 有关系吗?

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    Retrofit 2.6.0 或更新版本已内置 suspend 支持。

    可能您正在使用Kotlin Coroutine Adapter。这个库依赖反射来检测返回类型是否为Deffered。见here

    这是一个使用 Retrofit 2.6.0 的示例:

    interface RemoteInterface{
    
      @GET("/data/mydata")
      suspend fun getData(): MyModel
    }
    

    在您的 ViewModel 中:

    fun retrieveDataFromRemote() {
      viewModelScope.launch {
          val model = remoteInterface.getData()
          // do something with model
      }
    }
    

    【讨论】:

    • 那么如果我使用Retrofit 2.6.0,我不需要使用Deferred?但是我该如何使用 await 呢?
    • 可以在任何其他挂起函数或协程中调用挂起函数。看到这篇博文proandroiddev.com/…
    • 在您的 ViewModel 中,您可以这样做:viewModelScope.launch { api.getData() }
    • 我在答案中添加了一个示例
    【解决方案2】:
    • 何时使用挂起,何时不使用?可以参考suspend

    • 从 Retrofit 2.6.0 或更高版本开始,它内置了暂停支持,不使用 Deferred

    【讨论】:

    • 那么如果我使用Retrofit 2.6.0,我不需要使用Deferred?但是我该如何使用 await 呢?
    • 示例:@GET("users/{login}") 暂停乐趣 fetchUserDetailsAsync(@Path("login") login: String): User
    • 仅从 Deferred 更改为 suspend,
    猜你喜欢
    • 2013-04-06
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多