Having coroutine wait for previous calls

帅比萌擦擦* 提交于 2021-01-27 20:16:03

问题


I still haven't fully grasped Kotlin coroutines yet.

Basically I want a coroutine to wait for any previous calls to finish before executing. The following code seems to work. But is it doing what I think it's doing?

private var saveJob: Job? = null

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

As far as I can tell, the code is doing what I want. But is it?


回答1:


Keep in mind that the launched code is concurrent to the code outside it. That means that what you wrote has a race condition: the outside code may have already assigned the new job to saveJob when you try to join() it, resulting in a deadlock.

I guess what you want is to trigger a save operation in the background, and the operation itself will pull all the data to save from somewhere else. You probably don't want a queue of save jobs, just ensure that everything is saved at the point you call save(). If you called save a bit earlier and a new save job hasn't yet started, those two calls can be coalesced into a single save operation.

Furthermore, you say that you have a suspending database operation. Suspending code doesn't belong in the IO dispatcher, which is there only if you have to perform many blocking operations concurrently.

All told I'd suggest using an actor:

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

fun save() = someScope.launch {
    actor.send(Unit)
}



回答2:


Basically it's not wrong. Although I would recommend just to go imperatively just as you program outside of a coroutine. Saving the response in the variable would ensure that the next line won't execute until the response of the first:

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

  }
}


来源:https://stackoverflow.com/questions/58593236/having-coroutine-wait-for-previous-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!