<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>null29fun CoroutineScope.asyncString(str: String, time: Long) = async { 30 delay(time) 31 str 32 } 33 <lambda>null34fun 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