I was trying Kotlin coroutines using a test file. What I observed is that the async{..} block , completes and then the next async block starts.
@Test
fun `xyz`() {
runBlocking {
val x = async {
x()
}
val y = async {
y()
}
val z = async {
z()
}
println("x, y, z -> ${x.await()} , ${y.await()}, ${z.await()} ")
}
}
fun x() = "x".also {
repeat(1000) {
println("waiting for network response.")
}
println("returning x")
}
fun y() = "y".also { println("returning y") }
fun z() = "z".also { println("returning z") }
In this code block I can see "returning y" and "returning z" only gets printed after the call to x() completes. Thats not how I expect Kotlin to run things parallelly. Could you please tell me the change I need to do to run the three calls concurrently or not wait for one to complete. PS - The code in test method can be run directly on main as well. :)
This is an interesting question and the reason why you are not getting the expected asynchronous behavior comes from your
runBlockingfunction and theBlockingEventLoopit creates as context. When running coroutines with this dispatcher, you will only work in a singleThread. Though technicallyasynclaunches coroutines asynchronously, for your example, you'll only see this behaviour when performing non blocking operations likedelayand this is only becausedelayschedules but this is of course not what you are looking for. The scope contexts you may be interested in forasyncto work areIO,DefaultorUnconfined, but I think in your caseDefaultapplies best. Keep in mind that unit tests usually need to start a blocking context like withrunBlockingorrunTestand so using acoroutineScopemay work only if you are already in a coroutine scope (i.e. in asuspendfunction or withing a scope started withrunBlocking) and if the context is already non-blocking. Here are 3 different versions of your own code with 3 different examples: a blocking one and two non-blocking with 2 different styles.Note that, as suggested by @Joffrey, although the examples are used to make clear points about
contextsandscopesinKotlincoroutines, the following example would be the most correct one to implement in regards to respecting a concept very important in coroutines calledstructured concurrency. This is a bit more complex concept to understand, but in general we should avoid context switching when it is not necessary:Also make sure to consider using assertions in these tests. They are not complete. They are only focused on anwering your question.