xref: /aosp_15_r20/external/kotlinx.coroutines/kotlinx-coroutines-core/jvm/test/guide/example-select-05.kt (revision 7a7160fed73afa6648ef8aa100d4a336fe921d9a)

<lambda>null1 // This file was automatically generated from select-expression.md by Knit tool. Do not edit.
2 package kotlinx.coroutines.guide.exampleSelect05
3 
4 import kotlinx.coroutines.*
5 import kotlinx.coroutines.channels.*
6 import kotlinx.coroutines.selects.*
7 
8 fun CoroutineScope.switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String> {
9     var current = input.receive() // start with first received deferred value
10     while (isActive) { // loop while not cancelled/closed
11         val next = select<Deferred<String>?> { // return next deferred value from this select or null
12             input.onReceiveCatching { update ->
13                 update.getOrNull()
14             }
15             current.onAwait { value ->
16                 send(value) // send value that current deferred has produced
17                 input.receiveCatching().getOrNull() // and use the next deferred from the input channel
18             }
19         }
20         if (next == null) {
21             println("Channel was closed")
22             break // out of loop
23         } else {
24             current = next
25         }
26     }
27 }
28 
<lambda>null29 fun CoroutineScope.asyncString(str: String, time: Long) = async {
30     delay(time)
31     str
32 }
33 
<lambda>null34 fun main() = runBlocking<Unit> {
35     val chan = Channel<Deferred<String>>() // the channel for test
36     launch { // launch printing coroutine
37         for (s in switchMapDeferreds(chan))
38             println(s) // print each received string
39     }
40     chan.send(asyncString("BEGIN", 100))
41     delay(200) // enough time for "BEGIN" to be produced
42     chan.send(asyncString("Slow", 500))
43     delay(100) // not enough time to produce slow
44     chan.send(asyncString("Replace", 100))
45     delay(500) // give it time before the last one
46     chan.send(asyncString("END", 500))
47     delay(1000) // give it time to process
48     chan.close() // close the channel ...
49     delay(500) // and wait some time to let it finish
50 }
51