Coroutines

    [Coroutine Flow] conflate를 이용해 최신 데이터 collect 하기

    collectLatest를 이용한 최신 데이터 collect의 한계점 그림1과 같이 데이터 발행 시간 사이의 간격보다 데이터를 처리하는 suspend fun이 수행하는 시간이 오래 걸릴 경우, 새로 들어온 데이터는 계속해서 소비되지 못한다. 즉 이런 상황에서 collectLatest를 쓸 경우 중간 데이터를 하나도 얻지 못하고 마지막 데이터만을 얻을 수 있다. 예를 들어 아래 그림2와 같이 데이터 발행에 0.1초가 걸리는데 데이터 소비에 1초가 걸릴 경우 하나도 소비가 안되고 마지막 데이터만이 소비된다. conflate을 이용해 최신 데이터 collect하기 이를 해결하는 방법은 간단하다. 한 번 시작된 데이터 소비는 끝날 때까지 하고 데이터 소비가 끝난 시점에서의 가장 최신 데이터를 다시 소비하는 것이..

    [Coroutine Flow] buffer 이용해 발행과 소비를 위한 Coroutine 분리하기

    collect에서 데이터 발행과 소비가 일어나는 방식 flow의 collect를 사용하면 하나의 Coroutine에서 발행과 소비가 같이 일어나기 때문에 데이터가 발행된 후 소비가 끝나고 나서 다시 다음 데이터가 발행된다. 즉 발행과 소비가 순차적으로 일어난다. 이를 그림으로 표현하면 다음과 같다. 하지만 이 방식은 매우 비효율적이다. 발행하는 쪽이나 소비하는 쪽의 delay를 미리 처리하지 않는다면 발행부와 소비부 양쪽에서 모두 delay가 생기기 때문이다. 예를 들어 다음과 같이 발행에 1초 소비에 3초가 걸리는 코드가 있다고 해보자. 그림2의 로그에서 볼 수 있듯이 collect를 사용하면 데이터를 발행하는데 1초 소비하는데 3초가 걸려서 총 4초가 발행과 소비에 사용된다. 즉, 발행에 지연(del..

    [Coroutine Flow] collect와 collectLatest의 차이는 무엇인가?

    collect를 사용한 데이터 소비의 한계점 Flow는 Coroutine상에서 Reactive한 프로그래밍을 할 수 있도록 만들어진 데이터 파이프 라인이다. Flow는 데이터를 발행하는 역할을 하며 Flow에서 발행하는 데이터는 collect의 action 파라미터에 의해 소비된다. public suspend inline fun Flow.collect(crossinline action: suspend (value: T) -> Unit): Unit = collect(object : FlowCollector { override suspend fun emit(value: T) = action(value) }) collect의 인자로 들어가는 action 블록은 flow에서 발행된 데이터를 순차적으로 받아 su..

    [Coroutine Flow] 3. stateIn 사용하여 Flow를 StateFlow로 변환하기

    Flow와 StateFlow 우리는 리액티브 프로그래밍을 할 때 여러 데이터 흐름(flow)를 하나로 합쳐 하나의 데이터 흐름(Flow)으로 만들어낸다. 예를 들어 아래의 그림3에서는 Flow가 3개 있고 이것이 합쳐져 하나의 Flow를 만들어낸다. 이러한 상황은 흔하다. 예를 들어 우리가 영화 평점 앱을 만든다고 할 경우 영화에 대한 정보, 사용자에 대한 정보, 사용자의 영화의 평점에 대한 정보를 각 테이블에서 가져와 하나의 객체로 만들어야 한다. 하나로 만들어진 Flow는 UI에서 사용되기 위해 StateFlow로 변환되어야 한다. 이 UI에서는 이 StateFlow를 구독하여 항상 최신 데이터를 발행받는다. 이것이 가능하기 위해서는 Flow를 StateFlow로 변환하는 로직이 필요하다. 또한 St..

    [Coroutine Flow] 2. Flow와 StateFlow의 차이는 무엇인가?

    Flow의 한계 Flow는 데이터의 흐름이다. Flow는 데이터의 흐름(flow)을 발생시키기만 할 뿐 데이터가 저장되지 않는다. 따라서 flow만을 이용해 안드로이드의 UIState를 업데이트 하기 위해서는 두가지 방법이 가능했다. 화면이 재구성 될때마다 다시 서버 혹은 DB로부터 데이터 가져오기 Flow로부터 collect한 데이터를 ViewModel에 저장해놓고 사용하기 1번 방법은 비효율적이다. 예를 들어 안드로이드에서는 화면이 회전되었을 때마다 onDestroy가 호출된 후 다시 onCreate이 호출되는데, 이때마다 새로운 데이터를 서버 혹은 DB로부터 가져와야 하기 때문이다. 2번 방법은 효율적이다. 아래 그림의 ViewModel이 살아있는 범위에서 볼 수 있듯이 ViewModel은 onDe..