[英]How to wait for a Kotlin coroutine to finish
我已经阅读了数十篇文章,但不知何故,在我的情况下似乎没有一个答案有效。
我想要实现的是在 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
}
如果没有涉及其他代码,那么它应该按此顺序运行。
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
逻辑。
您是否有理由不只是在协程中运行最终代码?
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) }
)
}
然后您将更新的项目传递给您的最终 function:
lifecycleScope.launch {
val updatedItem = viewModel.updateData(myItem)
doSomethingElseWithUpdatedmyItem(updatedItem)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.