首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >暂停Coroutine悬挂

暂停Coroutine悬挂
EN

Stack Overflow用户
提问于 2019-10-13 03:19:24
回答 2查看 888关注 0票数 0

试着深入到合作中去。我有一个suspendCancellableCoroutine,它应该获取一个网络响应。我从查尔斯身上可以看出,网络呼叫已被发送并成功返回。然而,我的应用程序只是挂在网络请求线上。

代码语言:javascript
复制
private suspend fun fetchVisualElementsFromServer(clubId: String): VisualElements {
    return suspendCancellableCoroutine { cont ->
        visualElementsService.fetchVisualElementsForClub(clubId)
            .enqueue(object : Callback<ResultVisualElements> {
                override fun onResponse(
                    call: Call<ResultVisualElements>,
                    response: Response<ResultVisualElements>
                ) {
                    if (response.isSuccessful) {
                        response.body()?.let {
                            if (it.result == RESULT_SUCCESS) {
                       saveVisualElementsResponseInSharedPreferences(it.visual_elements)
                                cont.resume (it.visual_elements)
                            } else {
                                cont.cancel()  //edit
                            }
                        } ?: cont.cancel() //edit
                    } else {
                        cont.cancel(IOException("${response.code()}: ${response.errorBody()}"))
                    }
                }
                override fun onFailure(call: Call<ResultVisualElements>, t: Throwable) {
                    Timber.e(t, "visual elements fetch failed")
                    cont.cancel() // edit
                }
            })
    }
}

它挂在这里:

VisualElementsService.kt

代码语言:javascript
复制
fun fetchVisualElementsForClub(clubId: String): Call<ResultVisualElements> {
    return dataFetcherService.getVisualElementsForClub(clubId)
}

我在这里错过了什么?我试图使fetchVisualElementsForClub()成为一个挂起函数,但这只会使suspendCancellableCoroutine抛出一个Suspension functions can only be called within coroutine body错误。但我以为他的身体还在体内?

任何帮助都很感激。谢谢。

编辑

下面我对Rene的回答作出回应,我想补充几点。

您说得对,我错过了三个cont.cancel()调用。我修改了OP。好点子。

我在整个suspendCancellableCoroutine中都有断点,因此任何可能的场景(成功、失败等)都是如此。会被击中的。但那回拨从来没有登记过。

想知道fetchVisualElementsForClub()中是否缺少什么东西来将回调传递给suspendCancellableCoroutine。这似乎是挂在这里的。

EN

回答 2

Stack Overflow用户

发布于 2019-10-13 09:54:13

必须在回调处理中的每个分支上调用cont.resume()cont.cancel()。但在你的例子中,至少有三起案件失踪。

  1. 如果响应成功但没有提供任何对象,则什么都不调用。如果响应成功,则
  2. 不为空,但it.result不是您调用的RESULT_SUCCESS
  3. 如果onFailure中有问题,则什么也不调用。H 211G 212

只要不调用resumecancel,协同线就会保持挂起,这意味着挂起。

票数 2
EN

Stack Overflow用户

发布于 2019-10-13 04:07:21

当您使用挂起关键字时,您正在告诉该函数应该在coroutine中调用,例如:

代码语言:javascript
复制
suspend fun abc(){
   return
}

当您想调用上面的函数时,您必须在协同线中调用它,如下所示:

代码语言:javascript
复制
GlobalScope.launch {
  abc()
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58360319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档