Dmytro TOLSTYI
01/21/2019, 7:59 AMsuspend
function which I can't solve: I got function suspend fun one()
which executes some code and then calls a function that accepts a callback function as a param. But, this param function is not suspend. The issue is that I need to call another suspend fun from that callback param function. Here's an example:
suspend fun one() {
doSomething()
funWithNonSuspendCallback("data") {
two() // I need to call it from here but this is not suspend scope anymore
}
}
suspend fun two() {
}
uli
01/21/2019, 8:11 AMsuspend fun one() {
doSomething()
suspendingWrappedFunWithNonSuspendCallback("data")
two() // Back into coroutine scope after callback was called
}
}
Dmytro TOLSTYI
01/21/2019, 8:16 AMlouiscad
01/21/2019, 8:29 AMsuspendCoroutine { continuation ->
// call continuation.resume(Unit) when callback is invoked
}
If you support cancellation, you can also use this;
suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
// unregister callback
}
// call continuation.resume(Unit) when callback is invoked
}
Dmytro TOLSTYI
01/21/2019, 9:02 AMsuspendCoroutine
will create a new suspension point, right? It means that my code will be blocked until this part is executed. This is not exactly what is callback function flow...louiscad
01/21/2019, 9:09 AMresume
is called back on the Continuation
. You register the callback in the lambda passed to suspendCoroutine
or suspendCancellableCoroutine
, which will be called immediately, and will then suspend waiting for your callback to invoke resume
.Dmytro TOLSTYI
01/21/2019, 9:16 AMfun one()
suspendCoroutine {}
fun two()
In this case fun two()
is not going to be executed unless suspendCoroutine
is not resumed, right?louiscad
01/21/2019, 9:45 AMone()
suspendCoroutine { c ->
// Some code
}
two()
then yes, just like all suspend function calls, it will suspend until it's resumed, and only then, two()
wil be executed.Dmytro TOLSTYI
01/21/2019, 9:50 AMone()
bindEventListenerWithCallback(callback)
two()
The flow is one()
-> bindEventListenerWithCallback()
-> two()
-> callback()
Looks like the flow is different in this caselouiscad
01/21/2019, 9:52 AMcallback()
in your snippet…Dmytro TOLSTYI
01/21/2019, 9:52 AMcallback
is going to be called when appropriate event is firedlouiscad
01/21/2019, 9:54 AMbindEventListenerWithCallback
is a suspend function but behaves the way you tell me, then it's not implemented correctly (using suspendCoroutine
or suspendCancellableCoroutine
properly should fix this)Dmytro TOLSTYI
01/21/2019, 10:04 AMbindEventListenerWithCallback
is not a suspend
function. What it does is just register handler that will be called when some kind of event occurslouiscad
01/21/2019, 10:14 AMsuspendCoroutine
or its cancellable version if supported.uli
01/21/2019, 11:34 AMsuspend fun suspendingWrappedFunWithNonSuspendCallback(data: String): Value = suspendCoroutine { cont ->
funWithNonSuspendCallback("data") { cont.resume(it) }
}
Dmytro TOLSTYI
01/22/2019, 4:54 AM