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

标签 kotlin asynchronous kotlin-coroutines suspend

我正在从一个挂起函数调用一个 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/

相关文章:

java - 如何将res文件从项目放到同一文件夹中的jar中?

具有多个发射的 Android 单元测试流程

multithreading - 如何限制 kotlin 协程的最大并发性

java - 如何更改 Kotlin 中 RecyclerView 中每个 Even 值元素的颜色?

LiveData 的 Java 扩展方法

java - Picasso 不会下载有效的 URL

android - 如何在 Android 应用程序未激活/未聚焦时显示 View ?

javascript - websql成功回调在查询后无法访问变量

javascript - 如何使用 React Hooks API 管理异步函数

javascript - 循环加载D3中的多个JSON文件: index is always the last one