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 AMDmytro TOLSTYI
01/21/2019, 9:07 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?Dmytro TOLSTYI
01/21/2019, 9:38 AMlouiscad
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 firedDmytro TOLSTYI
01/21/2019, 9:52 AMlouiscad
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