Kotlin/Kotlin Coroutine

[Kotlin/Coroutine] 공식문서에서의 Flow 1

주 녕 2022. 5. 14. 02:59
728x90

포스팅 내용과 작성된 코드는 Kotlin 공식문서에서 참조한 내용입니다.

Multiple Value를 나타낼 수 있는 방법

Sequence Suspend function Flow
- Collections의 chain calls 패턴의 오버헤드를 피할 수 있는 방법 중 하나
- lazy evaluation
- 계산을 위해 blocking 되지 않는 비동기 - 비동기로 처리하는 stream of value

아마 이런 느낌이지 않을까...하고 그려본 도식

  • Flow의 builder 함수는 flow
  • flow { ... } builder block 내부 코드는 suspend 일 수 있음
  • flow에서 방출되어야 할 값은 emit()을 이용해서 처리할 수 있음

 

Flow는 Cold

  • flow는 sequence와 유사한 cold stream이다
Cold Stream Hot Stream
- 하나의 Consumer에게 값을 보냄
- 생성된 이후에 누군가 소비를 시작하면, 데이터를 발행
→ 데이터베이스 접근, URL을 통해 서버 값을 읽는 경우
- 하나 이상의 Consumer에게 값을 보냄
- 데이터 발생 시작 이후부터 모든 소비자에게 같은 데이터를 발행
  (구독자가 없는 경우에도 데이터를 발행함)
→ 네트워크 상태 정보 등

 

Flow는 Cancel이 가능

  • flow collection은 flow가 cancellable suspending function 안에서 suspend될 때, 취소가 가능함

 

Flow builder

  • flow { ... } : 기본 선언
  • flowOf() : fixed set of value를 emit
    • fun flowOf(vararg elements: T): Flow
    • flowOf(1, 2, 3)
  • .asFlow() : extension 함수를 이용해 다양한 collections, sequences를 flow로 변환 가능

 

Flow Operator

Intermediate Flow Operator

  • Flow는 collections나 sequences를 변환하는 것과 동일한 방법으로 operator을 사용해서 변환 가능 (chain call)
  • operator도 cold stream / but, operator 호출은 suspending function 그 자체는 아님
  • sequences에서의 operator과 같은 기능을 하지만, 차이점은 operator 내부의 코드 블록이 suspend 함수를 호출할 수 있다는 것
suspend fun performRequest(request: Int): String {
    delay(1000) // imitate long-running asynchronous work
    return "response $request"
}

fun main() = runBlocking<Unit> {
    (1..3).asFlow() // a flow of requests
        .map { request -> performRequest(request) }
        .collect { response -> println(response) }
}
  • Transform operator : transform, map, filter
  • Size-limiting operator : take

Terminal flow operator

  • flow의 collection을 시작하는 suspending function
    • 다양한 collections로 전환 가능 : toList, toSet
    • first value : first
    • single 값을 방출하는 것을 보장 : single
    • flow를 value로 reduce : reduce, fold
val sum = (1..5).asFlow()
    .map { it * it } // squares of numbers from 1 to 5                           
    .reduce { a, b -> a + b } // sum them (terminal operator)
println(sum) // 55

 

Flow는 sequential하다

  • Flow의 개별적인 collection은 여러 flow에서 사용되는 operator를 사용하지 않는 한 순차적으로 수행됨
  • collection은 terminal operator을 호출하는 coroutine에서 직접 작동함
  • 각각의 emitted value는 intermediate operator에 의해서 upstream → downstream으로 처리된 후,
    terminal operator에게 전달됨

 


 

정리

Flow는

  • 비동기로 처리할 수 있는 stream of value
  • 하나의 Consumer에게 값을 보내며, lazy하게 값을 발생하는 Cold Stream
  • 취소가 가능함
  • 3가지의 builder를 통해서 선언 가능
  • sequences나 collections에서 사용한 operator과 동일한 기능의 operator를 사용할 수 있음
    • 차이점은 operator의 코드 블럭에서 suspend 함수를 호출할 수 있다는 점
  • 순차적으로 처리됨

 


 

reference >

728x90