Coroutine Select Expression
Use select expression to await the first result from multiple suspending operations or channels.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.selects.select
fun main() = runBlocking {
// Select from multiple channels
val chan1 = Channel<String>()
val chan2 = Channel<String>()
launch {
delay(100)
chan1.send("From channel 1")
}
launch {
delay(50)
chan2.send("From channel 2")
}
// First to arrive wins
val fastest = select {
chan1.onReceive { it }
chan2.onReceive { it }
}
println("Fastest: $fastest") // From channel 2
// Select from multiple async operations
suspend fun fetchFromApi1(): String {
delay(200); return "API 1 result"
}
suspend fun fetchFromApi2(): String {
delay(100); return "API 2 result"
}
val result = coroutineScope {
val api1 = async { fetchFromApi1() }
val api2 = async { fetchFromApi2() }
select {
api1.onAwait { it }
api2.onAwait { it }
}
}
println("First API: $result")
// Select with timeout
val slowChannel = Channel<String>()
launch {
delay(5000) // very slow
slowChannel.send("Slow result")
}
val timedResult = select {
slowChannel.onReceive { it }
onTimeout(1000) { "Timed out" }
}
println("Timed: $timedResult") // Timed out
// Fan-in with select
val producers = (1..3).map { id ->
produce {
repeat(3) {
delay((50..150).random().toLong())
send("Producer-$id: item-$it")
}
}
}
repeat(9) {
val item = select {
producers.forEach { producer ->
producer.onReceive { it }
}
}
println("Received: $item")
}
println("Done")
}Use Cases
- Racing multiple async operations
- Timeout handling for slow operations
- Priority-based channel consumption
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
Coroutines — launch, async, and Structured Concurrency
Write concurrent code with Kotlin coroutines: launch, async/await, structured concurrency, and dispatchers.
Best for: Parallel API calls in backend services
Channels — Producer-Consumer with Coroutines
Communicate between coroutines with Channels: produce, actor pattern, fan-out/fan-in, and select.
Best for: Producer-consumer patterns in coroutines
Structured Concurrency Patterns
Master coroutine structured concurrency: coroutineScope, async/await, fan-out/fan-in, and parallel map.
Best for: Parallel I/O operations with concurrency limits
Coroutine Channels Producer Consumer
Use Kotlin channels for coroutine communication: buffered, conflated, fan-out, and fan-in patterns.
Best for: Coroutine-based producer-consumer patterns