让协程等待以前的调用



我还没有完全掌握 Kotlin 协程。

基本上,我希望一个协程在执行之前等待任何先前的调用完成。以下代码似乎有效。但它在做我认为它正在做的事情吗?

private var saveJob: Job? = null
fun save() {
saveJob = someScope.launch {
saveJob?.join()
withContext(Dispatchers.IO) {
// suspending database operation
}
}
}

据我所知,代码正在做我想做的事。但真的是这样吗?

请记住,launched代码与其外部的代码并发。这意味着您编写的内容具有争用条件:当您尝试join()新作业时,外部代码可能已经将新作业分配给saveJob,从而导致死锁。

我想你想要的是save后台触发一个操作,操作本身会从其他地方提取所有数据来保存。您可能不想要save作业的队列,只需确保在调用save()时保存所有内容即可。如果您稍早调用save,并且新的保存作业尚未启动,则可以将这两个调用合并为单个save操作。

此外,您说您有一个挂起的数据库操作。挂起代码不属于IO调度程序,仅当您必须同时执行许多阻塞操作时,调度程序才存在。

所有人都告诉我我建议使用演员:

val actor = someScope.actor<Unit>(capacity = CONFLATED) {
// suspending database operation
}
fun save() = someScope.launch {
actor.send(Unit)
}

基本上没有错。尽管我建议像在协程之外编程一样强制进行。将响应保存在变量中将确保下一行在第一行的响应之前不会执行:

scope.launch(someDispatcher){
val dataFromDelayingCode = getDelayingData()
if(delayingData.isFinished){
}
}

最新更新