스터디를 하며 코틀린 Flow에 대하여 접하게 되었는데 새롭기도 하고 코루틴을 사용할 때 매우 유용하게 쓰인다고 하여 정리해 보았다.
Asynchronous Flow
Suspending 함수는 단일 값이 비동기적으로
만약 비동기식으로 계산된 여러 값이 있다면 어떻게 반환해야할까? 이를 위해 코틀린 Flows가 존재한다
잠깐, 코루틴에서 일시중단 함수가 필요한 이유는 무엇일까?
해당 질문에 대한 답으로 설명하기 좋은 그림을 다른 블로그에서 가져왔다.
해당 그림은 메인 스레드의 코루틴 1에서 작업이 수행되고 io 스레드의 코루틴 3에서 작업 3이 같이 수행되고 있다. 코루틴 1에서 코루틴 3의 작업 3의 결과가 필요한 작업이 나와 코루틴 1이 잠시 중지되고 작업 3의 결과값을 반환받기 까지 중지된다.
그리고 코루틴 2가 메인 스레드를 점유하며 작업 2가 수행되고 완료한다. 코루틴3의 작업 3이 완료되면 코루틴 1은 이 값을 전달받고 재개되게 된다.
이 예시로써 일시중단 함수가 왜 필요한 것인지 알 수 있게 된다.
바로 3가지 이유에서 사용하는데,
첫째, 비동기 작업을 막지 않고 수행되기 때문에
둘째, 긴 작업을 수행하는 동안에도 일시 중단하고 다른 코루틴을 실행할 수 있어 효율적이기에
셋째, 여러 코루틴을 동시에 사용할 때 CPU나 I/O 자원을 효율적으로 활용할 수 있다.
그렇다면 그중 Asynchronous Flow의 필요성이 무엇일까?
첫째, 비동기 작업에서 발생하는 데이터를 연속적으로 처리하며 필요한 경우 데이터 버퍼링을 하거나 중간 처리과정을 수행 할 수 있다.
둘째, 백프레셔 처리를 하는데도 도움이 된다. (백프레셔란 데이터 생산자와 소비자 간의 속도차이로 인해 발생하는 문제를 해결하기 위한 매커니즘)
여기서 또 하나의 의문점이 생겼다.
비동기 작업을 다루는 suspending 함수와 Flow의 차이점이 무엇일까?
Suspending 함수:
일시중지가능 함수로 코루틴 내에서 호출되며 코루틴의 실행을 일시중단, 재개 시킬 수 있다. 반환값과 예외를 다루기도 한다.
차이점:
suspending 함수는 비동기 작업을 단일 값으로 다루고 Flow는 비동기 작업의 연속된 값을 다루는데 사용된다. 때로는 Suspending 함수와 Flow를 함께 사용하여 비동기 작업을 조율하고 Suspending 함수내에서 Flow를 사용하거나 Flow에서 Suspending 함수를 호출하는 것도 가능하다.
코드로써 이해하기 위해 예제 코드를 작성해보았다. 위의 코드의 결과는 아래 사진과 같이 도출된다.
코드를 통해서 알게 된 것을 정리해보았다.
- Flow 타입에 대한 builder 함수를 flow라고 한다.
- Flow{} 의 builder 블록은 suspend를 사용할 수 있다.
- emit 함수를 사용하여 flow에서 데이터를 방출하고 collect함수를 사용하여 flow에서 값을 수집할 수 있다.
emit과 collect란?
flow가 여러개의 값을 비동기적으로 생성하고 전달하는 기능을 하는데 이때 각 값을 생성하고 전달하기 위해서 emit이라는 함수를 사용한다.
즉 emit 함수를 사용해서 flow 내부에서 데이터를 발생시키고 외부로 전달하는 것이라고 할 수 있다.
이렇게 flow에서 방출된 값을 메인 스레드에서 수집하고 출력하기 위해 collect 함수를 활용한다.
추가적으로 왜 굳이 데이터를 방출하고 다시 수집할까라는 의문점을 가지게 되어 두 함수의 필요성을 추가적으로 조사해 보았다. 우선 emit 함수를 사용해서 flow 내에서 데이터를 생성하면 데이터가 비동기적으로 다음단계로 흐르며 이를 통해 비동기 데이터 스트림을 생성하기에 필요하고 collect 함수는 각 데이터를 순차적으로 수집하여 처리하는데 사용된다.
이로써 순차적인 처리를 보장하며 각 데이터에 대한 로직을 적용할 수 있기에 이를 사용한다.
Flow의 transformation연산에 대하여
2. Filter 연산
조건에 맞는 요소만을 선택하여 새로운 Flow를 생성한다.
3. Transform 연산
각 요소를 변환하는데 사용되며 변환함수가 각 요소에 대해 호출된다.
Transform 연산내에서 새로운 값을 emit 하여 변환된 Flow를 생성한다.
'Frontend > Kotlin' 카테고리의 다른 글
Hilt 배워서 적용해보기 (0) | 2023.09.22 |
---|---|
collect와 collectLatest (0) | 2023.09.08 |
MVVM 패턴 적용기(2) (0) | 2023.08.15 |
Coroutine 개념 (0) | 2023.08.04 |
MVVM 패턴 적용기(1) (0) | 2023.07.29 |