What if I need to setup callback wrapped in the co...
# coroutines
e
What if I need to setup callback wrapped in the coroutine and only after call some action. Can I achieve it only with async? Or I need to use more thread synchronisation. Problem: I need to add listener for DB update but DB save happens async and I can not hook into it.
Copy code
val waithForDBSave = async { setupListenerAndWait() } 
db.save() // I want to wait before executing here to be sure listener was setup
waitForDBSave.await()
I probably should use semaphore
d
Hi! If it is guaranteed that
setupListenerAndWait()
will not suspend until the listener is installed, you can do this:
Copy code
val waithForDBSave = async(start = CoroutineStart.UNDISPATCHED) {
e
It is written like
Copy code
suspendCoroutine { continuation ->
        val saveListener = object : SaveListener {
            override fun onSaved() {
                    continuation.resume(Unit)
            }
        }
        db.addListener(saveListener)
    }
d
suspendCoroutine
won't suspend until its block finishes executing, so
UNDISPATCHED
should work.
👍🏼 1
e
So, your suggestion should work
Thank you!
n
could you explain me solution ?
e
Sure! Without coroutines it is sequential execution code. Coroutines are adding points for suspension - where execution stops until it is resumed. Then it runs sequential again till the next suspension point. Every sequential execution runs on a thread. So proposal is to make start of async undispatched - so it should execute on the same thread until the next suspension point. And since listener setup happens there that guarantees that code which is suppose to notify listener will happen in sequential manner after.
z
Probably better to use
launch
instead of
async
if your callback doesn't have a result.
👍🏼 1
e
Thanks! Off topic - After long discussion here we are going to change API so there is more clean api to make things in sync
n
i didn't understand why you are using this code ? for whom?