정상에서 IT를 외치다

[리엑티브 연습] flatMap, concatMap, switchMap 본문

안드로이드

[리엑티브 연습] flatMap, concatMap, switchMap

Black-Jin 2019. 6. 25. 17:32
반응형

안녕하세요. 블랙진입니다.

리엑티브 연습 포스팅입니다.


이터러밍 상황에서 flatMap, concatMap, switchMap 어떻게 동작되는지 살펴보겠습니다.



FlatMap


새로운 Observable 흐름을 만들어 주며 데이터의 흐름은 보장되지 않습니다.

val balls = listOf("하나", "둘", "셋")

Observable.interval(100L, TimeUnit.MILLISECONDS)
.map(Long::toInt)
.map { id -> balls[id] }
.take(balls.size.toLong())
.flatMap { ball ->
Observable.interval(200, TimeUnit.MILLISECONDS)
.map { "$ball ☆" }.take(2)
}
.subscribe(::println)

Thread.sleep(2000)

interval 함수는 일정한 간격을 가지고 데이터를 발행합니다. 0부터 주어진 시간 간격을 가지고 1씩 증가합니다.


 

 0.1초

 0.2초

 0.3초

 0.4초

 0.5초

 0.6초

 0.7초

 1OB

 하나

 둘

 셋

 

 

 

 

 2OB

 

 

하나 ☆

 

 하나 ☆

 

 

 2OB

 

 

 

 둘 ☆

 

 둘 ☆

 

 2OB

 

 

 

 

 셋 ☆

 

 셋 ☆


표에 있는 시간순으로 데이터가 발행됩니다. 이를 순서대로 나열하면 아래와 같습니다.


하나 ☆

둘 ☆

하나 ☆

셋 ☆

둘 ☆

셋 ☆


이게 이터리밍 되었을 때의 데이터 입니다.




ConcatMap


먼저 들어온 데이터 순서대로 처리해서 결과를 낼 수 있도록 보장해줍니다. 

Observable.interval(100L, TimeUnit.MILLISECONDS)
.map(Long::toInt)
.map { id -> balls[id] }
.take(balls.size.toLong())
.concatMap { ball ->
Observable.interval(200, TimeUnit.MILLISECONDS)
.map { "$ball ☆" }.take(2)
}
.subscribe(::println)

Thread.sleep(2000)

flatMap만 concatMap으로 변경했습니다.


 

 0.1초

 0.2초

 0.3초

 0.4초

 0.5초

 0.6초

 0.7초

 0.8초

 0.9초

 1.0초

 1.1초

 1.2초

 1.3초

 1OB

 하나

 둘

 셋

 

 

 

 

 

 

 

 

 

 

 2OB

 

 

  하나 ☆

 

  하나 ☆

 

 

 

 

 

 

 

 

 2OB

 

 

 

 

 

 

 둘 ☆

 

 둘 ☆

 

 

 

 

 2OB

 

 

 

 

 

 

 

 

 

 

 셋 ☆

 

 셋 ☆


표에 있는 시간순으로 데이터가 발행됩니다. 이를 순서대로 나열하면 아래와 같습니다.


하나 ☆

하나 ☆

둘 ☆

둘 ☆

셋 ☆

셋 ☆


이터리밍이 발생하지 않고 들어간 데이터 순서대로 발생하고 있는것을 확인할 수 있습니다.




SwitchMap


순서를 보장하기 위해 기존에 진행 중이던 작업을 바로 중단합니다.

Observable.interval(100L, TimeUnit.MILLISECONDS)
.map(Long::toInt)
.map { id -> balls[id] }
.take(balls.size.toLong())
.switchMap { ball ->
Observable.interval(200, TimeUnit.MILLISECONDS)
.map { "$ball ☆" }.take(2)
}
.subscribe(::println)

Thread.sleep(2000)

flatMap만 switchMap으로 변경했습니다.


 

 0.1초

 0.2초

 0.3초

 0.4초

 0.5초

 0.6초

 0.7초

 1OB

 하나

 둘

 셋

 

 

 

 

 2OB

 구독

 중지


 

 

 

 

 2OB

 

 구독

 중지

 

 

 

 

 2OB

 

 

 구독

 

 셋 ☆

 

 셋 ☆


표에 있는 시간순으로 데이터가 발행됩니다. 이를 순서대로 나열하면 아래와 같습니다.


셋 ☆

셋 ☆


표에서 보듯 2OB가 구독되었지만 1OB가 데이터를 보냈으므로 바로 중지가 됩니다.




주의사항


위에 적은 0.1초 0.2초 ... 에 따른 1OB, 2OB 결과는 직접 시간을 찍어본게 아닌 "doOnNext()를 통해 이런식으로 결과가 나오니깐 표가 이렇게 되겠구나라"는 저의 뇌피셜입니다. 연습용 포스팅 이지만 혹시나 오해가 되지 않게 참고 부탁드립니다. 

반응형
Comments