Coroutines: how to bridge blocking and non blocking code?

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"

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

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

1 Like