Coroutines: how to bridge blocking and non blocking code?

#1

I have a Kotlin/JS project with Kotlin 1.3.30 and Kotlinx Coroutine Extensions

compile group: ‘org.jetbrains.kotlinx’, name: ‘kotlinx-coroutines-core-js’, version: ‘1.2.0-alpha-2’*

I am wondering how I should launch my couroutines in this scenario:

fun main () {

// setup with suspending calls
one().await()
two().await()
three().await()


// sequencial code here

}

I can’t run the suspending block in “runBlocking” as it’s not available in JS. It works fine if I mark main itself as suspend but then I get this exception once my call hierachy get’s to deep:

Exception in completion handler ResumeAwaitOnCompl…d by RangeError: Maximum call stack size exceeded"

#2

The official solution is to either use suspend main or to run root coroutine via GlobalScope.launch and then live entirely in suspend world. There is also this issue. I do not recommend to use this approach for simply going into suspend world, but it could solve similar problems.

1 Like
#3

Thanks to @darksnake reply I now made this completely ghetto function:

fun <T> completeDeferred(deferred: Deferred<T>, handler : (T) -> Unit) {
println("checking deferred")
if( !deferred.isCompleted) {
    println("not complete, setting timeout")
    window.setTimeout({checkDefered(deferred, handler)}, 10)
} else {
    println("completed, calling handler")
    handler.invoke(deferred.getCompleted())
}

}

Also, it turns out my error above isn’t from the coroutines but from kotlinx.html. Oh well …

Edit: actually there error came form Chrome itself as I’ve been creating an infinite number of input fields recursively