코루틴의 플로우는 데이터 스트림(비동기 스트림)이며, 코루틴 상에서 리액티브 프로그래밍을 지원 하기 위한 구성요소이다.
리액티브 프로그래밍에는 하나의 데이터를 발행하는 발행자가 있고 해당 발행자는 데이터의 소비자에게 지속적으로 데이터를 전달하는 역할을 한다. 이것이 데이터 스트림
이다.
fun flowSomething(): Flow<Int> = flow {
repeat(10) { // collect를 하지 않으면 동작 X
emit(Random.nextInt(0, 500))
delay(10L)
}
}
runBlocking {
flowSomething().collect { value -> // collect 요청 시 값을 보냄
println(value)
}
}
flow {}
: 플로우를 만드는 빌더 (플로우 빌더)
Flow<Int>
: 제네릭 타입(Int)이 플로우가 어떤 값을 방출하는지 지정
emit
: 스트림에 값을 보내는 함수
collect
: 스트림을 사용하기 위한 함수
콜드 스트림 : 요청이 있는경우에 값을 전달한다. 보통 1:1로 값을 전달.
핫 스트림 : 0개 이상의 상대를 향해 지속적으로 값을 전달.
플로우는 콜드 스트림이기 때문에 요청 측에서 **collect**를 호출해야 값을 방출한다.
withTimeoutOrNull
을 사용해서 플로우를 취소할 수 있다.
fun flowSomething(): Flow<Int> = flow {
repeat(10) { // collect를 하지 않으면 동작 X
emit(Random.nextInt(0, 500))
delay(10L)
}
}
runBlocking {
val result = withTimeoutOrNull(500L) {
flowSomething().collect { value ->
println(value)
}
true
} ?: false
if(!result) {
println("취소되었습니다.")
}
}
flow
이외에도 flowOf
, asFlow
등의 플로우 빌더가 있다.
runBlocking {
// flowOf() : 여러 값을 인자로 전달해 플로우를 만든다.
flowOf(1, 2, 3, 4, 5).collect { value ->
println(value)
}
}
// flow {
// emit(1)
// emit(2)
// emit(3)
// emit(4)
// emit(5)
// }.collect { println(it) }
flowOf()는 위 주석처리한 코드와 같다.
runBlocking {
// asFlow() : 컬렉션이나 시퀀스를 전달해 플로우로 만들 수 있다.
listOf(1, 2, 3, 4, 5).asFlow().collect {
println(it)
}
(6..10).asFlow().collect { value ->
println(value)
}
}
// flowOf(1, 2, 3, 4, 5).collect { ... }
위 주석한 코드와 같다.