【问题标题】:How to wait for a Kotlin coroutine to finish如何等待 Kotlin 协程完成
【发布时间】:2021-05-18 18:43:38
【问题描述】:

我已经阅读了几十篇帖子,但不知何故,我的情况似乎没有一个答案。

我想要实现的是在 Fragment 中等待 ViewModel 使用 Room 执行操作。

道:

@Query("SELECT * FROM my_table WHERE id = :id")
suspend fun getMyData(id: Long): List<Item>

在 ViewModel 中我不需要返回任何内容,只需使用数据库中的一些数据更新我的变量。我在这里也尝试过其他方法,即返回 Deferred

视图模型:

suspend fun updateData(myItem: Item) {
    for (myField in myItem.fields) {
        myField.someOtherField = myDao.getMyData(myField.id)
    }
}

我尝试过使用 runBlocking、lifecycleScope.launch 和 async.await() 等待,但总是得到相同的结果。我需要处理更新的项目。

片段:

runBlocking {
    val job = launch{
        viewModel.updateData(myItem)
    }
    job.join()
    doSomethingElseWithUpdatedmyItem(myItem) //this always executes before viewModel.updateData(myItem) even starts
}                            

【问题讨论】:

  • 您的代码应该可以正常工作。是否涉及其他代码?
  • @LouisWasserman 我没有看到任何相关的内容。唯一想到的是 runBlocking 块位于观察者内部,而 myItem 实际上是从该观察者返回的值。会不会有影响?

标签: android kotlin android-room kotlin-coroutines


【解决方案1】:

如果不涉及其他代码,则应按此顺序运行。

runBlocking {
    println("run blocking")
    val job = launch {
        delay(1000)
        println("launch new job")
    }
    job.join()
    println("do something")
}

此代码将打印:

run blocking
launch new job
do something

在你的情况下,我会使用 withContext/async 来表示 viewModel.updateData 逻辑。

【讨论】:

    【解决方案2】:

    您是否有理由不只是在协程中运行最终代码

    lifecycleScope.launch {
        viewModel.updateData(myItem)
        doSomethingElseWithUpdatedmyItem(myItem)
    }   
    

    这是使用协程的真正用途。

    不过,最终我想知道这里的问题是否在于您的项目的可变性。为什么不返回一组新项目而不是尝试改变现有项目?然后你会有类似的东西

    suspend fun updateData(myItem: Item): Item {
        return myItem.copy(
            fields = myItem.fields.map { field -> myDao.getMyData(field.id) }
        )
    }
    

    然后你会将更新后的项目传递给你的最终函数:

    lifecycleScope.launch {
        val updatedItem = viewModel.updateData(myItem)
        doSomethingElseWithUpdatedmyItem(updatedItem)
    }   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 2017-12-17
      • 2021-07-21
      • 2021-10-15
      • 2019-07-18
      • 2021-03-30
      • 2019-11-01
      相关资源
      最近更新 更多