• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 // This file was automatically generated from select-expression.md by Knit tool. Do not edit.
6 package kotlinx.coroutines.guide.exampleSelect05
7 
8 import kotlinx.coroutines.*
9 import kotlinx.coroutines.channels.*
10 import kotlinx.coroutines.selects.*
11 
12 fun CoroutineScope.switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String> {
13     var current = input.receive() // start with first received deferred value
14     while (isActive) { // loop while not cancelled/closed
15         val next = select<Deferred<String>?> { // return next deferred value from this select or null
16             input.onReceiveOrNull { update ->
17                 update // replaces next value to wait
18             }
19             current.onAwait { value ->
20                 send(value) // send value that current deferred has produced
21                 input.receiveOrNull() // and use the next deferred from the input channel
22             }
23         }
24         if (next == null) {
25             println("Channel was closed")
26             break // out of loop
27         } else {
28             current = next
29         }
30     }
31 }
32 
<lambda>null33 fun CoroutineScope.asyncString(str: String, time: Long) = async {
34     delay(time)
35     str
36 }
37 
<lambda>null38 fun main() = runBlocking<Unit> {
39     val chan = Channel<Deferred<String>>() // the channel for test
40     launch { // launch printing coroutine
41         for (s in switchMapDeferreds(chan))
42             println(s) // print each received string
43     }
44     chan.send(asyncString("BEGIN", 100))
45     delay(200) // enough time for "BEGIN" to be produced
46     chan.send(asyncString("Slow", 500))
47     delay(100) // not enough time to produce slow
48     chan.send(asyncString("Replace", 100))
49     delay(500) // give it time before the last one
50     chan.send(asyncString("END", 500))
51     delay(1000) // give it time to process
52     chan.close() // close the channel ...
53     delay(500) // and wait some time to let it finish
54 }
55