- 코루틴은 가장 먼저 완료되는 코루틴의 결과를 기다리는
select
함수를 제공함.
지연되는 값 선택하기
- 데이터를 요청한 뒤, 가장 빠른 응답을 얻는 쉬운 방법은
select
함수를 사용하고 내부에서 값을 기다리는 것임.
select
함수 내부에선 Deferred
값의 onAawait
함수를 호출함.
select
함수는 하나의 비동기 작업이 완료됨과 동시에 끝나게 되어 결괏값을 반환함.
suspend fun requestData1(): String {
delay(1000)
return "Data1"
}
suspend fun requestData2(): String {
delay(500)
return "Data2"
}
suspend fun askMultipleForData(): String = coroutineScope {
select<String> {
async { requestData1() }.onAwait { it }
async { requestData2() }.onAwait { it }
}
}
실행결과 : Data2
async
와 select
를 사용하면 코루틴끼리 경합하는 상황을 구현할 수 있음.
- 이 경우 스코프를 취소해야함.
also
를 호출한 뒤 다른 코루틴을 취소할 수 있음.
suspend fun askMultipleForData(): String = coroutineScope {
select<String> {
async { requestData1() }.onAwait { it }
async { requestData2() }.onAwait { it }
}.also { coroutineContext.cancelChildren() }
}
채널에서 값 선택하기
select
함수는 채널에서도 사용이 가능함.
ReceiveChannel.onReceive
: 채널이 값을 가지고 있을 때 선택됨. onReceive
가 선택되었을 때, select
는 람다식의 결괏값을 반환함.
ReceiveChannel.onReceiveCatching
: 채널이 값을 가지고 있거나 닫혔을 때 선택됨. 값을 나타내거나 닫혀있는 걸 알려주는 ChannelResult
를 받으며 이 값은 람다식의 인자임.
onReceiveCatching
가 선택되었을 때, select
는 람다식의 결괏값을 반환함.
Channel.onSend
: 채널의 버퍼에 공간이 있을 때 선택됨. 채널에 값을 보낸 뒤, 채널의 참조값으로 람다식을 수행함. onSend
가 선택되었을 때, select
는 Unit
을 반환함.