gpt4 book ai didi

kotlin - 如何在不阻塞调用函数的情况下从另一个挂起函数调用挂起函数?

转载 作者:行者123 更新时间:2023-12-05 06:08:47 25 4
gpt4 key购买 nike

我正在从一个挂起函数调用一个 Api,在它成功执行后,我需要调用另一个 Api(它也在另一个挂起函数中)。

    suspend fun updateSubscription(body: Map<String, Any>): NetworkResponse<SubscriptionUpdateResponse> =
withContext(Dispatchers.IO) {
val response = networkManager.execute(
networkManager.updateSubscriptionApi(body)
)
val data = response.body()
if (response.isSuccessful) {
fetchSubscriptions() // suspend function which call another api, should run without blocking
}
return@withContext parseNetworkResponse(response, data)
}

我想调用 updateSubscriptionApi 并在它成功执行后,无阻塞地调用 fetchSubscription 并返回 updateSubscription 结果。

目前,fetchSubscription 也阻止了 updateSubscription。我尝试像这样在 async block 中调用 updateSubscription 但没有成功。

async{ updateSubscription() }

如何在不阻塞 updateSubscription 的情况下调用 fetchSubscriptions()

最佳答案

不幸的是,您要求函数同时挂起和启动在函数返回时仍处于事件状态的并发工作,这在 Kotlin 中被认为是一种反模式,实现起来有一些困难。

但首先,简单的事情:

  1. 您确定需要 IO 调度程序吗?你说网络调用是挂起的,这意味着是非阻塞的,不需要专门的 IO 调度器。

  2. 如果您确实需要它(它实际上是一个阻塞调用),请不要将所有代码包装在其中,而只是那个调用。

现在,困难的部分。为了也能够启动协同程序,考虑在哪个范围内启动它至关重要。Kotlin 强烈建议使用结构化并发,这意味着在定义明确的 UI 元素(事件等)范围内启动所有内容.在您的情况下,您必须将范围作为参数显式传递给函数。通常你会将其声明为 CoroutineScope 的扩展,但由于 coroutineContext 的命名冲突,这不适用于挂起函数,它既是全局 >valCoroutineScope 的属性。这意味着您的代码可能如下所示:

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

suspend fun updateSubscription(
scope: CoroutineScope,
body: Map<String, Any>
): NetworkResponse<SubscriptionUpdateResponse> {
val response = withContext(Dispatchers.IO) { // only if you need it!
networkManager.execute(networkManager.updateSubscriptionApi(body))
}
if (response.isSuccessful) {
scope.launch { fetchSubscriptions() }
}
return parseNetworkResponse(response, response.body())
}

关于kotlin - 如何在不阻塞调用函数的情况下从另一个挂起函数调用挂起函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65017974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com