Coroutine 정리 (비동기)

Park Jae Hong·2022년 8월 10일
0

Flow 란?

: Coroutine의 Flow는 비동기적인 데이터 스트림이며, 코루틴 상에서 리액티브 프로그래밍 지원 하기 위한 구성요소이다.

리액티브 프로그래밍이란?

: 리액티브 프로그래밍이란 데이터가 변경 될 때 이벤트를 발생시켜서 데이터를 계속해서 전달하도록 하는 프로그래밍 방식을 뜻한다.

  • 기존 명령형 프로그래밍에서는 데이터의 소비자는 데이터를 요청한 후 받은 결과값을 일회성으로 수신한다. 하지만, 이러한 방식은 데이터가 필요할 때마다 결과값을 매번 요청해야한다는 점에서 매우 비효율적이다. 리액티브 프로그래밍에서는 데이터를 발행하는 발행자가 있고 데이터의 소비자는 데이터의 발행자에 구독 요청을 한다. 그러면 데이터의 발행자는 새로운 데이터가 들어오면 데이터의 소비자에게 지속적으로 발행한다.
    즉, 리액티브 프로그래밍에는 하나의 데이터를 발행하는 발행자가 있고 해당 발행자는 데이터의 소비자에게 지속적으로 데이터를 전달하는 역할을 한다. 우리는 이것을 데이터 스트림이라고 한다.

데이터 스트림 구성 요소

image
출처 : https://kotlinworld.com/175

  • Producer(생산자)
  • Intermediary(중간 연산자)
  • Consumer(소비자)

Producer(생산자)

: 데이터를 발행하는 역할을 한다. Flow에서의 Producer는 flow{ } 블록 내부에서의 emit()을 통해 데이터를 생성한다.

Intermediary(중간 연산자)

: 생산자가 데이터를 생성했으면 중간 연산자는 생성된 데이터를 수정한다.

(대표적인 중간 연산자는 map(데이터 변형), filter(데이터 필터링), onEach(모든 데이터마다 연산 수행) 등의 중간 연산자가 있다.)

Consumer(소비자)

: 중간 연산자가 생산자가 생성한 데이터를 변환하여 소비자로 데이터를 전달한다. Flow에서는 collect를 이용해 전달된 데이터를 소비할 수 있다.


Flow 생성 방법

  • flowOf(..) 함수를 사용하여 고정된 값 집합에서 flow를 만든다.

  • flow { .. } 빌더 함수로 순차적 호출에서 emit 함수로 임의의 flow를 구성.

  • channelFlow { .. } 빌더 함수를 통해 잠재적으로 동시 호출에서 send 함수로의 임의의 flow를 구성.

  • MutableStateFlow 및 MutableSharedFlow는 해당 생성자 함수를 정의하여 직접 업데이트 할 수 있는 핫 flow를 생성.

Flow constraints

Flow 인터페이스의 모든 구현은 아래에 자세히 설명된 두 가지 주요 속성을 준수해야 한다.

  • context 보존.
  • Exception transparency (예외 투명성)
    : 이런 특성은 flow를 사용하여 코드에 대한 로컬 판단을 수행하고 업스트림 flow emitter가 다운 스트림 flow collector와 별도로 개발 할 수 있는 방식으로 코드를 모듈화하는 기능을 보장한다. flow의 사용자는 flow에서 사용하는 업스트림의 구현 세부 정보를 알 필요가 없음.

내부 함수

  • buffer
    : 버퍼는 지정된 용량의 채널을 통하여 값을 방출하며 별도의 코루틴에서 collector를 실행합니다.

  • cancellable
    : 각 방출에 대한 취소 상태를 확인하고 flow 콜렉터가 취소된 경우 해당 취소 원인을 던지는 flow를 반환합니다. flow 빌더 및 SharedFlow의 모든 구현은 기본적으로 cancellable 될 수 있습니다.

  • catch
    : flow 완료되었을 때 예외를 포착하고 포착한 예외와 함께 인자에 지정된 action을 호출합니다. 이 연산자는 다운스트림 흐름에서 발생하는 예외에 대해 투명하며 flow를 취소하기 위해 던지는 예외는 catch하지 않습니다.

  • collect

  1. 인자가 지정되지 않은 익스텐션은 지정된 flow를 수집하지만 모든 방출된 값을 무시하는 터미널 flow 연산자 입니다. 수집 중 또는 제공된 flow에서 예외가 발생하는 경우 이 예외는 이 메소드에서 다시 발생합니다.
  2. 인자가 지정된 익스텐션은 제공된action으로 지정된 flow를 수집하는 터미널 flow 연산자입니다.
  • combine
    : 각 flow에서 가장 최근에 방출한 값을 조합하여 인자로 주어진 transform 함수와 함께 값이 생성된 flow를 반환합니다.
  • conflate : 압축된 채널을 통해 flow 방출값을 압축하여 별도의 코루틴에서 콜렉터를 실행합니다. 이로 인해 콜렉터가 느려서 방출자가 일시 중단되지 않지만 콜렉터는 항상 가장 최근의 값을 방출한다는 것입니다.
  • count
    : flow의 요소 수를 반환합니다. predicate 인자를 넣어주면 predicate 조건에 해당하는 요소의 수만 반환합니다.
  • drop
    : 인자로 주어진 count가 음수일 경우 예외를 던지며, 값을 방출하기 시작할 때 주어진 count 값 만큼 방출값을 무시하는 flow를 반환합니다.
  • filter
    : 지정된 predicate와 일치하는 값만 포함하고 있는 flow를 반환합니다.
  • flowOn
    : 이 flow가 실행되는 context를 지정된 context로 변경합니다. 이 연산자는 합성 가능하며 고유한 context가 없는 이전 연산자에만 영향을 미칩니다. 이 연산자는 context 보존 특성을 가집니다. 또한 context는 다운스트림 flow로 유출되지 않습니다.
  • fold
    : initial 값부터 시작하여 operation 인자의 acc 값과 현재 값으로 계산된 값과 각 요소를 적용하여 값을 누적합니다.
  • launchIn
    : scope에서 지정된 flow의 컬렉션을 시작하는 터미널 flow 연산자입니다. scope.launch { flow.collect() } 의 줄임입니다.
  • map
    : 지정된 transform 함수를 원래 flow의 각 값에 적용한 결과가 포함된 flow를 반환합니다.
  • onCompletion
    : 취소 예외 또는 실패를 action 매개 변수로 전달하여 flow가 완료되거나 취소된 후 지정된 action을 호출하는 flow를 반환합니다.
  • onEach
    : 업스트림 flow의 각 값이 다운스트림에서 방출되기 전에 지정된 action을 호출하는 flow를 반환합니다.
  • onEmpty
    : 이 flow가 완료되었을 때 요소를 방출하지 않고 지정된 action을 호출합니다. action의 수신자는 FlowCollector 이므로 onEmpty는 추가 요소를 방출할 수 있습니다. 예를 들어 다음과 같습니다.

❗ 이외에도 다양한 함수들이 존재


Inheritors

  • AbstractFlow : Flow의 상태 저장 구현을 위한 기본 클래스. 또한 context 보존에 필요한 모든 프로퍼티를 요구하며, 프로퍼티를 위반할 경우 IllegalStateException을 발생.

  • SharedFlow : 모든 콜렉터가 내보낸 값을 브로드캐스트 방식으로 공유하여 내보낸 값을 얻는 hot Flow . 활성화 상태의 인스턴스가 콜렉터의 존재와 독립적으로 존재하기 때문에 hot이라고 한다. 이것은 flow { .. } 함수에 의해 정의된 것과 같은 일반적인 Flow와 반대 개념. 일반 Flow는 cold에 속하며 각 콜렉터에 대해 개별적으로 시작.


참고 : https://medium.com/hongbeomi-dev/kotlin-coroutine-flow-ac07cfdca42d, https://kotlinworld.com/175

profile
The people who are crazy enough to think they can change the world are the ones who do. -Steve Jobs-

0개의 댓글