我正在从一个挂起函数调用一个 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 中被认为是一种反模式,实现起来有一些困难。
但首先,简单的事情:
您确定需要
IO
调度程序吗?你说网络调用是挂起的,这意味着是非阻塞的,不需要专门的 IO 调度器。如果您确实需要它(它实际上是一个阻塞调用),请不要将所有代码包装在其中,而只是那个调用。
现在,困难的部分。为了也能够启动协同程序,考虑在哪个范围内启动它至关重要。Kotlin 强烈建议使用结构化并发,这意味着在定义明确的 UI 元素(事件等)范围内启动所有内容.在您的情况下,您必须将范围作为参数显式传递给函数。通常你会将其声明为 CoroutineScope
的扩展,但由于 coroutineContext
的命名冲突,这不适用于挂起函数,它既是全局 >val
和 CoroutineScope
的属性。这意味着您的代码可能如下所示:
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/