Android의 Kotlin 코루틴 - 2(Flow)

김재원·2022년 1월 11일
0

코루틴

목록 보기
2/3
post-thumbnail

이전글에서는 코루틴이 무엇인가에 대해서 알아보았었습니다. 그리고 이글에서는 flow란 무엇인가에 대해서 알아보겠습니다.

ReacticeX를 먼저 익히고 coroutine을 공부한 저로써는 flow를 이해하기 정말 쉬웠습니다😏. flow는 ReacticeX에서의 Observable과 똑같았는데요, Observable 에서 처럼 map 함수도 쓸 수 있고, zip도 있는 등, 이해하기 정말 쉬웠습니다.

그래서 flow가 뭔데?

서론에서는 혹시 저처럼 RxJava를 먼저 공부하셨던 분이 계시면 저 문구가 flow를 이해하는데에 도움이 될것 같아서 ReactiveX와 연관시켜보았습니다😌.
coroutine에서 suspend함수는 단일값만 출력합니다. 하지만 리엑티브(반응형) 프로그램을 개발하다보면 데이터를 순차적으로 받아야할 경우가 있죠. 이럴때 flow를 통해서 데이터를 받는것입니다.
즉, 데이터의 흐름을 만드는것인데요. 데이터 흐름은 다음과 같이 만들어 집니다.
위 그림은 왼쪽부터 소비자, 중개자, 생산자를 표현한 그림입니다.

  • 생산자는 데이터를 생산합니다. Android 개발 관점에서 보면 서버와의 통신을 통해 데이터를 가져온것 정도로 생각할 수 있겠습니다. 데이터가 만들어진것이죠.
  • 중개자는 데이터를 가공, 수정합니다. 생산자가 만든 데이터를 필요에 맞게 변경하는것이죠. map함수등을 사용할 수 있습니다.
  • 소비자는 데이터를 사용합니다. 마지막에 데이터를 사용하는 viewModel 혹은, view등이 될 수 있습니다.

Flow 생성하기(생산자)

flow는 FlowBuilder를 통해 만들 수 있습니다🙂.

class Datasource {
   suspend fun fetchData(): Flow<String> {
      return flow { // flowBuilder
        for(value in 0..3) {
           delay(1000)
           emit(value.toString()) //데이터 방출(생산)
        }
      }
    }
}

fetchData()는 0부터 3까지의 데이터를 1초간격으로 생산하는 함수입니다. flow빌더를 통해 흐름을 만들고, emit함수를 통해 데이터를 생산하였죠😏.

주의해야할 점

  • 흐름은 순차적입니다. 그래서 flow 안에서 suspend 함수를 호출했다면 suspend함수가 반환될 때 까지 정지합니다.
val dataSource = flow{
   for(count in 0..3){
     val result = fetchData() // fetchData가 return 된 후 다음 코드가 실행됩니다.
     emit(result+" return")
   }
}

suspend fun fetchData(): String {
    delay(1000)
    return "data"
}
  • flow빌더에서는 다른 coroutineContext의 값을 생산(emit)할 수 없습니다. 그러므로 새 코루틴을 만들거나 withContext블록을 사용하여 다른 coroutineContext에서 emit을 호출하면 안됩니다.(꼭 필요하다면 flowOn연산자 사용)

Flow 수정하기(중개자)

flow는 map 함수를 통해 수정할 수 있습니다.

datasource.map{ data-> data + "!" }

datasource에서 "data return"이 생성되었었다면 map 함수를 통해 "data return!"이 됩니다.

Flow 수집하기(소비자)

flow는 터미널 연산자를 통해 수집됩니다. 터미널 연산자들은 collect, single, reduce, toList 등이 있습니다.

  • collect: 모든 데이터를 수집합니다.
  • single: 단일 데이터(하나만)를 수집합니다.
  • first: 단일 데이터(맨 처음에 생성된 데이터)를 수집합니다.
  • toList & toSet: 생성된 데이터들을 mutable collection으로 수집합니다.
  • fold: 생성된 데이터들을 주어진 연산을 이용하여 최종 결과를 수집합니다.
  • collectIndexed: collect와 같은 연산이지만 index를 추가로 수집합니다.

이런 터미널 연산자들이 있으니, 필요에 따라 자신에게 맞는 터미널 연산자를 사용하시면 되겠습니다😊.

이렇게해서 flow에 대해서 알아보았습니다🙂. flow를 잘 활용하시면 더욱 편한 개발을 하실 수 있을것 같습니다.
즐거운 개발 되세요😌.

profile
항상 배울 것을 찾는 개발자입니다🔥.

0개의 댓글