Coroutines Flow 3편 –

흐름 터미널 연산자

Flow의 터미널 연산자는 흐름 수집을 시작하는 일시 중지 기능*1입니다.

모으다 연산자는 가장 기본적인 연산자이지만 사용하기 쉽게 해주는 다른 터미널 연산자가 있습니다.

  • 다른 컬렉션으로 변환 목록 그리고 설정 같은 교환원.*2
  • 첫 번째 값만 얻으려면 첫 번째 연산자를 사용하여 하나의 값만 반환되도록 합니다.

    싱글 운영자.*3
  • 흐름을 값으로 줄이는 감소 또는 접기 연산자입니다.

예를 들어 :

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는 콜드 스트림이기 때문에 터미널 연산자가 실행될 때까지 출력 값 수집을 시작하지 않습니다.

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

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

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

*삼. first()는 여러 개가 반환되더라도 하나만 반환합니다.

여러 개를 발급받아도 상관없습니다.

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

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

그러나 하나만 써야 할 때 여러 개를 쓰는 경우를 잡아야 할 수도 있습니다.

이 경우 single()이 사용됩니다.

single은 값을 반환하지 않는 흐름에 대해 NoSuchElementException을 생성하고 세 개 이상의 값을 반환하는 흐름에 대해 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 {

흐름에서 하나만 내보내는 경우:

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

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

흐름에서 값이 반환되지 않는 경우

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
    }
}


이 문서는 공식 코루틴 문서를 번역한 것입니다.

원래의: 비동기 흐름 – 터미널 흐름 연산자

원본 텍스트의 최종 편집: 2022년 9월 28일


흐름은 순차적이다

개별 흐름의 각 컬렉션은 여러 흐름에 적용되는 특수 연산자를 사용하지 않는 한 순차적으로 실행됩니다.

컬렉션은 터미널 연산자를 호출하는 코루틴과 직접 작동합니다.

기본적으로 새로운 코루틴은 실행되지 않습니다.

각 출력 값은 업스트림에서 다운스트림으로 중간 운영자에 의해 처리된 다음 터미널 운영자에게 전달됩니다.

정수에서 짝수를 필터링하고 문자열에 매핑하는 다음 예를 고려하십시오.

(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


이 문서는 공식 코루틴 문서를 번역한 것입니다.

원래의: 비동기 흐름 – 흐름은 순차적입니다.

원본 텍스트의 최종 편집: 2022년 9월 28일