英文:
How to wait for all nested async functions to complete in Kotlin?
问题
Here's the translated code portion:
我在Android移动应用程序中有以下代码。 我需要确保transaction.save()在调用dismiss()之前始终执行完成。 目前,它只有在某些情况下才能正常工作。 我感谢有关如何重构此代码以使其按照我期望的方式运行的任何建议。
private fun save() {
lifecycleScope.launch {
showLoader()
withContext(Dispatchers.IO) {
transaction.save()
}
dismiss()
}
}
transaction.save()方法的定义。 onTripEvent是另一个挂起函数,用于保存记录在设备数据库中,并将其发送到Web API。 我不会提供它的定义。
suspend fun save() {
tripRepository.updateTripSourceItem(this)
tripRepository.onTripEvent("Updated item etc.")
}
tripRepository.updateTripSourceItem的定义
suspend fun updateTripSourceItem(tripSourceItem: TripSourceItem) {
localDataSource.updateTripSourceItem(tripSourceItem)
api.putTripSourceItem(tripSourceItem).await()
}
localDataSource.updateTripSourceItem的定义
@Dao
interface TripDao {
@Update
suspend fun updateTripSourceItem(tripSourceItem: TripSourceItem)
}
api.putTripSourceItem的定义
interface api {
@POST("apiEndPoint")
fun putTripSourceItem(
@Body body: TripSourceItem
): Deferred<List
}
我知道在访问数据库时最佳实践是使用withContext(Dispatchers.IO),但我应该在哪个函数中使用它?是顶级的`save()`函数,`transaction.save()`,`tripRepository.updateTripSourceItem()`,还是都是?我考虑过在每个函数中都添加类似以下内容,但这似乎有些过度。
suspend fun save()
withContext(Dispatchers.IO) {
awaitAll(
async { tripRepository.updateTripSourceItem(this@TripSourceItem) },
async { tripRepository.onTripEvent("Updated item etc.") }
)
}
}
}
英文:
I have the following code in an Android mobile app. I need to make sure transaction.save() is always finished executing before dismiss() is called. Currently, it only works some of the time. I appreciate any advice on how to restructure this to run like I expect it to.
private fun save() {
lifecycleScope.launch {
showLoader()
withContext(Dispatchers.IO) {
transaction.save()
}
dismiss()
}
}
Definition of transaction.save() method. onTripEvent is another suspend function that saves a record in the device database, and sends it to a web API. I won't bother providing its definition.
suspend fun save() {
tripRepository.updateTripSourceItem(this)
tripRepository.onTripEvent("Updated item etc.")
}
Definition of tripRepository.updateTripSourceItem
suspend fun updateTripSourceItem(tripSourceItem: TripSourceItem) {
localDataSource.updateTripSourceItem(tripSourceItem)
api.putTripSourceItem(tripSourceItem).await()
}
Definition of localDataSource.updateTripSourceItem
@Dao
interface TripDao {
@Update
suspend fun updateTripSourceItem(tripSourceItem: TripSourceItem)
}
Definition of api.putTripSourceItem
interface api {
@POST("apiEndPoint")
fun putTripSourceItem(
@Body body: TripSourceItem
): Deferred<List<StatusResponse>>
}
I know it's best practice to use withContext(Dispatchers.IO) when accessing the database, but which function do I need that in? The top level save()
function, transaction.save()
, tripRepository.updateTripSourceItem()
, or all of the above? I thought about putting something like this in every function, but it seems like overkill.
suspend fun save()
withContext(Dispatchers.IO) {
awaitAll(
async { tripRepository.updateTripSourceItem(this@TripSourceItem) },
async { tripRepository.onTripEvent("Updated item etc.") }
)
}
}
}
答案1
得分: 1
你在你的DAO的updateTripSourceItem
中使用了suspend
。这样做就是在告诉Room:“请在你自己的时间里做这个,不要打扰我或让我等待”。
由于你想要等待数据库正确更新,移除suspend
就能解决问题,你就不需要用await
写样板代码。
英文:
You are using suspend
in your updateTripSourceItem
in your DAO.
When doing that, you are saying to Room "Make sure you do this at your own time, don't bother me or make me wait"
Since you want to wait until the database is properly updated, removing the suspend will do the trick and you won't need to do boilerplate code with awaits
答案2
得分: -2
Wrap the save call with async.
private fun save() {
lifecycleScope.launch {
showLoader()
async(Dispatchers.IO) {
transaction.save()
}.await()
dismiss()
}
}
英文:
Wrap the save call with async.
private fun save() {
lifecycleScope.launch {
showLoader()
async(Dispatchers.IO) {
transaction.save()
}.await()
dismiss()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论