【问题标题】:Return value from coroutine scope without runBlocking从协程范围返回值而不使用 runBlocking
【发布时间】:2021-08-17 18:32:54
【问题描述】:

我正在尝试根据 repo 调用的响应数据运行一个函数,但遇到了竞争条件/使用协程范围返回数据的问题。基于这两个伪代码块,我想知道是否可以得到一些帮助?

选项 1:如果不使用 runBlocking,则无法在协程范围内返回响应。

fun mainFunction(): Boolean {
  return subFunction(getResponse()) //returns boolean
}

private fun getResponse () {
  scope.launch{
    val response = async { someApiCall }.await()

    return response
  }
}

选项 2:在调用 subFunction 时,response 的值尚未初始化,从而导致错误。

lateinit var response: MutableList<>

fun mainFunction(): Boolean {
  return subFunction(response) //returns boolean
}

private fun getResponse () {
  scope.launch{
    response = async { someApiCall }.await()
  }
}

【问题讨论】:

  • 运行挂起方法并返回结果的方法本身应该是suspend 方法。为什么你的getResponse() 没有暂停?
  • 正如@ianhanniballake 提到的,getResponse 应该是suspend fun。你可以使用withContext(Dispatchers.IO)。那么在mainFunction中,可以使用scope.launchasync await不是必须的。
  • 你可以使用withContext从块中返回
  • 如果我需要为mainFunction 返回一个值(如布尔值),是否可以在不使其成为挂起函数或withContext 的情况下处理getResponse 返回?因为如果我们在 mainFunction 的协程中使用它,它只会返回类型 Unit 对吧? @TuanChau @ianhanniballake @Anania Jemberu
  • 是的,我也遇到过这种情况。我让该函数挂起并在我的片段的 runBlocking 块中调用它。

标签: android kotlin android-asynctask kotlin-coroutines coroutine


【解决方案1】:

案例1:主函数返回一些东西

suspend fun mainFunction(): Boolean = subFunction(getResponse())

fun subFunction(input: Response): Boolean {
    // Do something
    return something
}

suspend fun getResponse() = withContext(Dispatchers.IO) {
    someApiCall()
}

那么mainFunction的调用者是kick-and-forget,我们可以使用scope.launch

fun metaMainFunction() {
    scope.launch {
        val isSomething = mainFunction()
        // Do something with isSomething
    }
}

案例 2:mainFunction 是一劳永逸,我们将相同的行为应用于案例 1 的 metaMainFunction

fun mainFunction() {
    scope.launch {
        val response = getResponse()
        // Do something with response
    }
}

最佳实践是被调用者应该决定执行哪个线程。在这种情况下,我们应该始终使用withContext(Dispatchers.IO) 代替getResponse()

【讨论】:

    猜你喜欢
    • 2020-11-07
    • 2023-01-27
    • 2022-07-05
    • 2019-02-19
    • 2023-03-07
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多