Coroutines Flow 2편 - Flow 취소하기, Flow 빌더, Flow 중간 연산자

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

Flow 취소하기

Flow는 Coroutines의 기본적인 협력적인 취소를 따른다. 일반적으로, 취소 가능한 일시중단 함수(delay 같은)에서 Flow가 일시중단될 때 Flow로부터 값을 수집하는 것이 취소될 수 있다. 다음의 예는 Flow가 withTimeoutOrNull 블록에서 실행될 때, Flow가 시간 초과에 따라 어떻게 취소되고 코드 실행이 중지되는지 보여준다 :

 

fun simple(): Flow<Int> = flow { 
    for (i in 1..3) {
        delay(100)          
        println("Emitting $i")
        emit(i)
    }
}

fun main() = runBlocking<Unit> {
    withTimeoutOrNull(250) { // Timeout after 250ms 
        simple().collect { value -> println(value) } 
    }
    println("Done")
}

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

 

simple 함수의 flow에서 2개의 숫자만 방출되고, 다음과 같은 출력*1을 만드는 것에 주목하자 :

 

Emitting 1
1
Emitting 2
2
Done

📌 자세한 사항을 알고 싶으면 Flow cancellation checks 섹션을 확인하자.

 

 

 

 

 


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

*1. simple 함수 내부의 flow는 100ms을 기다리고 emit이 실행된다. Timeout 시간이 250ms이므로 2번째 것을 방출시키고 나서는 실행이 취소된다.

 


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

 

원문 : Asynchronous Flow - Flow cancellation basics

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

 


Flow 빌더

이전 예제들의 flow { ... } 빌더는 가장 기본적인 빌더이다. Flow를 선언할 수 있는 다른 빌더들도 있다.

 

  • flowOf 빌더는 정해진 값의 세트를 방출하는 Flow를 정의한다.
  • 다양한 Collection들과 Sequence들은 .asFlow() 확장 함수를 사용해 Flow로 변환될 수 있다.

 

(1..3).asFlow().collect { value -> println(value) }

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

 

 


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

 

원문 : Asynchronous Flow - Flow builders

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

 


Flow 중간 연산자

Flow들은 Collections, Sequence와 같이 연산자를 이용해 변환될 수 있다. 중간 연산자는 업스트림 Flow에 적용되어 다운스트림 Flow를 반환한다. 이러한 연산자들은 Flow만큼 차갑다. 이러한 연산자를 호출하는 것은 그 자체로 일시 중단 함수가 아니다. 이는 빠르게 작동해 새롭게 변환된 Flow를 반환한다.

 

기본 연산자들은 map 혹은 filter와 같은 친숙한 이름을 가지고 있다. 이러한 연산자들과 Sequence들의 중요한 차이점은 이 연산자들 내부의 코드 블록에서는 일시 중단 함수를 호출 할 수 있다는 점이다.

 

예를 들어 요청을 수행하는 것이 오래 걸리는 작업이고 일시 중단 기능으로 구현되어 있는 경우에도, 요청들을 받는 Flow를 map 연산자를 사용해 결과에 매핑할 수 있다.

 

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

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

 

이는 다음과 같이 3줄의 결과를 만들어 내며, 각 줄은 이전 줄로부터 1초 후에 나타난다.

 

response 1
response 2
response 3

 

Transform 연산자

Flow의 변환 연산자들 중에서 가장 일반적인 것은 transform이다. 이는 map이나 filter와 같은 간단한 변환을 모방하거나 복잡한 변환들을 구현하는데 사용할 수 있다. transform 연산자를 사용하면 임의의 횟수 만큼 값을 emit 할 수 있다.

 

예를 들어, transform을 사용하면 오래걸리는 비동기 요청을 하기 전에 문자열을 emit하고 그 응답을 기다릴 수 있다.

(1..3).asFlow() // a flow of requests
    .transform { request ->
        emit("Making request $request") 
        emit(performRequest(request)) 
    }
    .collect { response -> println(response) }

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

 

이 코드의 결과는 다음과 같다.

Making request 1
response 1
Making request 2
response 2
Making request 3
response 3

 

크기 한정 연산자

take과 같은 크기 한정 중간 연산자들은 해당 임계치에 도달했을 때 flow의 실행을 취소한다. Coroutines의 취소는 언제나 Exception을 throw하여 수행되므로, try { ... } finally { ... } 같은 모든 리소스 관리를 위한 기능들은 취소에서 정상적으로 작동한다.

 

fun numbers(): Flow<Int> = flow {
    try {                          
        emit(1)
        emit(2) 
        println("This line will not execute")
        emit(3)    
    } finally {
        println("Finally in numbers")
    }
}

fun main() = runBlocking<Unit> {
    numbers() 
        .take(2) // take only the first two
        .collect { value -> println(value) }
}

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

 

numbers() 함수 내부의 flow { ... } body*1의 실행이 두 번째 숫자를 emit하고 멈추는 것을 이 코드의 결과에서 확실하게 볼 수 있다.

 

1
2
Finally in numbers

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

*1. body는 { ... } 내부의 코드를 뜻한다. 

 


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

 

원문 : Asynchronous Flow - Intermediate flow operators

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

 


 

목차로 돌아가기

 

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

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

simplecode.kr

 

 

반응형

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

Coroutines Flow 4편 - Flow의 수집이 일어나는 Context, Flow Buffering - buffer, conflate, collectLatest  (0) 2023.02.28
Coroutines Flow 3편 - Flow 터미널 연산자, Flow는 순차적이다  (0) 2023.02.27
Coroutines Flow 1편 - 복수의 값들 표현하기, Flow는 차갑다  (0) 2023.02.25
Coroutine Context와 Dispatcher 5편 - Coroutine Scope  (0) 2023.02.24
Coroutine Context와 Dispatcher 4편 - 부모 Coroutine의 책임, Coroutines에 이름 짓기, Context 요소들 결합하기  (0) 2023.02.23


'공식 문서 번역/Coroutines 공식 문서' 카테고리의 다른 글
  • Coroutines Flow 4편 - Flow의 수집이 일어나는 Context, Flow Buffering - buffer, conflate, collectLatest
  • Coroutines Flow 3편 - Flow 터미널 연산자, Flow는 순차적이다
  • Coroutines Flow 1편 - 복수의 값들 표현하기, Flow는 차갑다
  • Coroutine Context와 Dispatcher 5편 - Coroutine Scope
심플코드
심플코드
프로그래밍을 어렵지 않게 풀어서 설명하는 기술 블로그
    반응형
  • 심플코드
    심플코드
    심플코드
  • 전체
    오늘
    어제
    • 분류 전체보기 (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)
  • 블로그 메뉴

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

  • 공지사항

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

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
심플코드
Coroutines Flow 2편 - Flow 취소하기, Flow 빌더, Flow 중간 연산자
상단으로

티스토리툴바