코루틴 flow는 코루틴 상에서 리액티브 프로그래밍을 지원하기 위해 만들어진 구현체
코루틴에서 데이터 스트림을 구현하기 위해서는 Flow를 사용해야 한다.
순차적으로 값을 배출해서, 정상적으로 완료하거나 에러를 던지는 비동기 데이터 스트림 입니다. 일시중단할 수 있는 함수는(Suspending function) 비동기적으로 하나의 값을 반환합니다. 하지만 비동기적으로 계산되어진 값을 여러개를 반환할 때 Flow를 사용합니다.
Flow의 사용을 알아보기 위해 데이터 스트림을 살펴보자. 위 데이터 스트림은 아래 세가지 구성요소를 가진다.
Producer (생산자)
Intermediary (중간 연산자)
Consumer (소비자)
데이터 스트림의 구성요소가 어떻게 작동하는 지 알아보면서 Flow의 사용법을 알아보자
DataStream : Producer
생산자는 데이터를 발행한다. 주로 Local 또는 Remote의 DataSource에서 데이터를 가져온다.
Flow에서의 Producer는 emit()을 통해 데이터를 생성한다.
class RemoteDataSource(
private val remoteApi: RemoteApi
) {
// 먼저 flow scope를 선언
fun getObjectFlow(): Flow<List<Object>> = flow {
while(true) {
val objs = remoteApi.fetchLastedObject() // remote 서버로 부터 데이터를 받아옴
emit(objs) // emit으로 데이터를 발행
delay(60000) // 60초 마다 반복
}
}
}
DataStream : Intermediary
생산자가 데이터를 생성했으면 중간 연산자는 생성된 데이터를 수정한다.
여기서 생성자가 A라는 객체의 데이터를 발행했지만 B라는 객체 데이터가 필요한 경우 Flow에서 지원하는 중간 연산자를 이용해 A객체를 B객체로 바꿀 수 있다.
map, filter ,onEach
class ObjectRepository(
private val objectRemoteDataSorce: ObjectRemoteDataSorce
) {
fun getObjectOfViewItem(locale : Locale) =
objectRemoteDataSorce.getObjectFlow().map{ it.filter (this.prop == prop)
}
View에 모든 처리가 완료된 가공된 데이터만을 전달하는 것이 좋다.
이를 위해 Intermediary에서 전달하기 위해 데이터를 가공한다.
DataStream : Consumer
중간연산자가 생산자가 생성한 데이터를 가공하여 소비자로 데이터를 전달한다.
안드로이드에서 소비자라 함은 UI 구성요소를 생각하면 된다.
Flow에서는 collect를 이용해 전달된 데이터를 소비할 수 있다.
class ObjectViewModel(
private val objectRepository: ObjectRepository
) : ViewModel() {
fun collectObjectOf(prop: Prop) =
viewModelScope.launch {
dustRepository.getObjectFlow().collect { obj ->
text = obj.prop ...
}
}
}
}
받은 object 데이터를 이용하여 viewModel 에서 필요한 처리를 하고, View에서 사용하면 된다.