https://kotlinlang.org logo
Title
s

Shmuel Rosansky [G]

01/17/2021, 5:42 PM
Any ideas why this prints: Inner Value: 0 Outer
fun main() {
   println("Outer")
   
   CoroutineScope(Dispatchers.Default).launch {
       getFlow()
            .onEach { println("Value: $it") }
            .collect()
   }
}


fun getFlow() = callbackFlow<Int> {
   println("Inner")
   delay(1)
   sendBlocking(0)
}
Shouldn't
Outer
get printed first?
m

Marc Knaup

01/17/2021, 5:55 PM
If I run it as is then it simply prints
Outer
and exits. That’s correct. If I make
main
wait a little after launching the coroutine the program terminates with an error:
Outer
Inner
Value: 0
Exception in thread "DefaultDispatcher-worker-1" java.lang.IllegalStateException: 'awaitClose { yourCallbackOrListener.cancel() }' should be used in the end of callbackFlow block.
Otherwise, a callback/listener may leak in case of external cancellation.
See callbackFlow API documentation for the details.
(That’s on Kotlin/JVM)
s

Shmuel Rosansky [G]

01/17/2021, 5:57 PM
Thanks for the response @Marc Knaup!Maybe it's an issue with the playground?
m

Marc Knaup

01/17/2021, 5:58 PM
That one just prints
Inner Outer
without anything else. Also correct. You run both in parallel so there’s no guarantee which one will happen first. Printing output isn’t always synchronous.
s

Shmuel Rosansky [G]

01/17/2021, 5:59 PM
oh, ok. So its a race on
println
?
m

Marc Knaup

01/17/2021, 6:00 PM
probably, yes
s

Shmuel Rosansky [G]

01/17/2021, 6:00 PM
cool, thanks 👍