Coroutines Flow 3편 - Flow 터미널 연산자, Flow는 순차적이다

2023. 2. 27. 22:13·공식 문서 번역/Coroutines 공식 문서
반응형

Flow 터미널 연산자

Flow의 터미널 연산자는 flow를 수집을 시작하는 일시정지 함수*1이다. collect 연산자는 가장 기본 연산자이지만, 사용을 더 쉽게 만드는 다른 터미널 연산자들도 있다.

 

  • 다양한 Collection으로의 변환을 수행하는 toList 와 toSet 같은 연산자.*2
  • 첫 값만 가져오기 위한 first 연산자와 하나의 값만 방출되는 것을 확인하는 single 연산자.*3
  • flow를 값으로 줄이는 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

 

 


📖 아래 내용은 독자의 이해를 위해 번역자가 추가한 글입니다.

*1. Flow는 차가운 스트림이기 때문에 터미널 연산자가 실행되어야 방출되는 값들을 수집이 시작된다.

*2. toList()는 다음과 같이 사용할 수 있다. 

suspend fun main() {
    coroutineScope {
        val flow = flow {
            emit(1)
            emit(2)
            emit(3)
        }

        println(flow.toList()) // [1, 2, 3] 출력
    }
}

 

*3. first() 는 여러 개가 방출되더라도 한 개만 출력된다. 여러개가 emit 되더라도 관계없다.

suspend fun main() {
    coroutineScope {
        val flow = flow {
            emit(1)
            emit(2)
            emit(3)
        }

        println(flow.first()) // 1 출력
    }
}

하지만 한 개만 방출되어야 할 때 여러개가 방출되는 경우를 잡고 싶을 수 있다.

 

이 때 single() 을 사용한다. single은 아무 값도 방출되지 않는 flow에 대해서는 NoSuchElementException을 발생시키며, 2개 이상의 값이 방출되는 flow에 대해서는 Illegal Argument Exception을 발생시킨다.

/**
 * The terminal operator that awaits for one and only one value to be emitted.
 * Throws [NoSuchElementException] for empty flow and [IllegalStateException] for flow
 * that contains more than one element.
 */
public suspend fun <T> Flow<T>.single(): T {

 

flow에서 하나만 방출될 때 :

suspend fun main() {
    coroutineScope {
        val flow = flow {
            emit(1)
        }

        println(flow.single()) // 1 출력
    }
}

 

flow에서 아무 값도 방출되지 않을 때

suspend fun main() {
    coroutineScope {
        val flow = flow<Int> {
        }

        println(flow.single())
        // Exception in thread "main" java.util.NoSuchElementException: Flow is empty
    }
}

 

둘 이상의 값들이 방출될 때

suspend fun main() {
    coroutineScope {
        val flow = flow<Int> {
            emit(1)
            emit(2)
        }

        println(flow.single())
        // Exception in thread "main" java.lang.IllegalArgumentException: Flow has more than one element
    }
}

 

 


이 글은 Coroutines 공식 문서를 번역한 글입니다.

 

원문 : Asynchronous Flow - Terminal flow operators

원문 최종 수정 :  2022년 9월 28일

 


Flow는 순차적이다

여러 Flow들에서 작동하는 특수한 연산자를 사용하지 않는 한 각 개별 Flow의 컬렉션은 순차적으로 동작한다. 컬렉션은 터미널 연산자를 호출하는 Coroutine에서 직접 동작한다. 기본적으로 어떠한 새로운 Coroutines도 실행되지 않는다. 방출된 각 값들은 중간 연산자들에 의해 업스트림에서 다운스트림으로 처리된 후 터미널 연산자에게 전달된다.

 

정수 중 짝수를 필터링 한 후 문자열에 매핑하는 다음 예제를 참조하자 : 

 

(1..5).asFlow()
    .filter {
        println("Filter $it")
        it % 2 == 0              
    }              
    .map { 
        println("Map $it")
        "string $it"
    }.collect { 
        println("Collect $it")
    }

📌 전체 코드는 이곳에서 확인할 수 있습니다.

 

이는 다음 결과를 생성한다.

 

Filter 1
Filter 2
Map 2
Collect string 2
Filter 3
Filter 4
Map 4
Collect string 4
Filter 5

 

 

 


이 글은 Coroutines 공식 문서를 번역한 글입니다.

 

원문 : Asynchronous Flow - Flows are sequential

원문 최종 수정 :  2022년 9월 28일

 


목차로 돌아가기

 

Kotlin Coroutines 공식 문서 한국어 번역본 : Coroutines 한 번에 정리하기

Kotlin Coroutines 공식 문서 번역을 시작하며 Kotlin Coroutines는 Kotlin을 위한 강력한 비동기 솔루션이다. 안드로이드 실무에서는 한동안 높은 점유율을 자랑한 RxJava를 Coroutines가 대체하고 있으며, 새로

simplecode.kr

 

반응형

'공식 문서 번역 > Coroutines 공식 문서' 카테고리의 다른 글

Coroutines Flow 5편 - 여러 Flow 하나로 합치기, Flow를 Flatten하기 - flatMapConcat, flatMapMerge, flatMapLatest  (0) 2023.03.01
Coroutines Flow 4편 - Flow의 수집이 일어나는 Context, Flow Buffering - buffer, conflate, collectLatest  (0) 2023.02.28
Coroutines Flow 2편 - Flow 취소하기, Flow 빌더, Flow 중간 연산자  (0) 2023.02.26
Coroutines Flow 1편 - 복수의 값들 표현하기, Flow는 차갑다  (0) 2023.02.25
Coroutine Context와 Dispatcher 5편 - Coroutine Scope  (0) 2023.02.24


'공식 문서 번역/Coroutines 공식 문서' 카테고리의 다른 글
  • Coroutines Flow 5편 - 여러 Flow 하나로 합치기, Flow를 Flatten하기 - flatMapConcat, flatMapMerge, flatMapLatest
  • Coroutines Flow 4편 - Flow의 수집이 일어나는 Context, Flow Buffering - buffer, conflate, collectLatest
  • Coroutines Flow 2편 - Flow 취소하기, Flow 빌더, Flow 중간 연산자
  • Coroutines Flow 1편 - 복수의 값들 표현하기, Flow는 차갑다
심플코드
심플코드
프로그래밍을 어렵지 않게 풀어서 설명하는 기술 블로그
    반응형
  • 심플코드
    심플코드
    심플코드
  • 전체
    오늘
    어제
    • 분류 전체보기 (96)
      • 안드로이드를 위한 Coroutines (2)
      • Unit Testing (19)
      • GitHub Actions (0)
      • 공식 문서 번역 (35)
        • Coroutines 공식 문서 (35)
      • 알고리즘 (7)
        • Kotlin 자료구조 (0)
        • 알고리즘 (7)
        • Kotlin으로 구현하는 자료구조 (0)
      • 코딩 테스트 (0)
      • Deep Learning (0)
      • Machine Learning Math (17)
        • Linear Algebra (17)
      • ML (0)
      • Docker (15)
      • Kubernetes (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 코틀린 코루틴의 정석 책 출간 소식
  • 인기 글

  • 태그

    junit
    mockito
    코루틴 Flow
    TensorFlow
    Kotlin
    unit test
    Coroutines Flow
    Coroutines Context
    pytorch
    코루틴
    도커
    numpy
    Coroutines
    unit testing
    컨테이너
    Machine Learning
    코루틴 채널
    Coroutines Channel
    coroutine
    Docker
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
심플코드
Coroutines Flow 3편 - Flow 터미널 연산자, Flow는 순차적이다
상단으로

티스토리툴바