리액티브 프로그래밍은 데이터 흐름과 전파를 선언적으로 표현하기 위한 프로그래밍 패러다임입니다. 코틀린은 이를 지원하는 강력한 기능을 제공합니다. 이번 포스트에서는 코틀린에서의 리액티브 데이터 흐름을 어떻게 제어할 수 있는지에 대해 다루겠습니다.
Flow와 Flow Operator
코틀린의 Flow
는 비동기 데이터 스트림을 표현하는 데 사용되며, Flow
를 조작하기 위해 여러 연산자(operator)를 사용할 수 있습니다. 예를 들어, map
, filter
, transform
등의 연산자를 사용하여 데이터를 매핑하거나 필터링할 수 있습니다.
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.*
fun main() = runBlocking {
(1..3).asFlow()
.map { it * it } // 제곱
.filter { it < 5 } // 5 미만 필터링
.collect { println(it) } // 결과 출력
}
위 예제에서는 1부터 3까지의 숫자를 제곱하고, 그 결과가 5 미만인 경우에만 출력하는 간단한 Flow
를 만들었습니다.
FlatMap과 Concat
Flow
에서는 flatMap
과 concat
이라는 유용한 연산자들을 제공합니다. flatMap
은 각 입력 요소에 대해 새로운 Flow
를 생성하고, 이를 하나의 Flow
로 합칩니다. concat
은 여러 Flow
의 요소를 순차적으로 결합합니다.
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.*
fun requestFlow(i: Int): Flow<String> = flow {
emit("$i: First")
delay(500) // 0.5초 대기
emit("$i: Second")
}
fun main() = runBlocking {
(1..3).asFlow()
.map { requestFlow(it) }
.flatMapConcat { it }
.collect { value -> println(value) }
}
위 예제에서는 flatMapConcat
을 사용하여 각 숫자에 대해 requestFlow
를 호출하고, 그 결과를 순서대로 출력하는 것을 볼 수 있습니다.
Retry 및 Error Handling
리액티브 시스템에서는 에러 처리가 매우 중요합니다. 코틀린의 Flow
에서는 retry
와 catch
를 사용하여 에러를 처리할 수 있습니다.
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.*
fun requestFlow(i: Int): Flow<String> = flow {
emit("$i: First")
delay(500) // 0.5초 대기
if (i == 2) {
throw RuntimeException("Error occurred for $i")
}
emit("$i: Second")
}
fun main() = runBlocking {
(1..3).asFlow()
.map { requestFlow(it) }
.catch { e -> emit("Error occurred: ${e.message}") }
.retry(2) // 최대 2번 재시도
.flatMapConcat { it }
.collect { value -> println(value) }
}
위 예제에서는 requestFlow
에서 2를 받았을 때 에러를 일으키도록 설정하고, catch
와 retry
를 사용하여 에러 처리를 하고 있습니다.
결론
코틀린의 리액티브 데이터 흐름을 조작하기 위한 연산자와 에러 처리 기능을 사용하면 더욱 강력하고 안정적인 비동기 코드를 작성할 수 있습니다. 이를 통해 다양한 비동기 상황에 대응할 수 있는 솔루션을 구현할 수 있을 것입니다.
참고 자료:
이상으로 코틀린에서의 리액티브 데이터 흐름 제어에 대해 알아보았습니다. 감사합니다!