일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 소프시스
- 한달어스
- 테트리스
- 목적중심리더십
- 자취필수템
- T자형인재
- 프래그먼트
- 안드로이드
- 좌식테이블
- 북한살둘레길
- 한달브런치북만들기
- 브런치작가되기
- 리얼하다
- 면접
- 끝말잇기
- 어떻게 나답게 살 것인가
- 목적 중심 리더십
- 베드테이블
- 베드트레이
- 함수형 프로그래밍
- 1일1커밋
- 커스텀린트
- 캐치마인드
- 재택근무
- 지지않는다는말
- 한달독서
- 한단어의힘
- 아비투스
- 소프시스 밤부 좌식 엑슬 테이블
- 슬기로운 온라인 게임
- Today
- Total
정상에서 IT를 외치다
[리엑티브 연습] flatMap, concatMap, switchMap 본문
안녕하세요. 블랙진입니다.
리엑티브 연습 포스팅입니다.
이터러밍 상황에서 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()를 통해 이런식으로 결과가 나오니깐 표가 이렇게 되겠구나라"는 저의 뇌피셜입니다. 연습용 포스팅 이지만 혹시나 오해가 되지 않게 참고 부탁드립니다.
'안드로이드' 카테고리의 다른 글
[Android, Context] Context 넌 무엇이더냐? (2) | 2019.07.02 |
---|---|
[리엑티브 연습] concat, zip (네트워크 통신 예제) (0) | 2019.06.26 |
[리엑티브 연습] AsyncSubject, BehaviorSubject, PublishSubject, ReplaySubject (0) | 2019.06.25 |
[리엑티브 연습] Observable, Single, Maybe, Completable (0) | 2019.06.25 |
[스트림 연습] Kotlin Collection Example (0) | 2019.06.25 |