일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 좌식테이블
- 한단어의힘
- 1일1커밋
- 베드테이블
- 한달어스
- 지지않는다는말
- 면접
- 베드트레이
- 함수형 프로그래밍
- 한달독서
- 커스텀린트
- 목적중심리더십
- 아비투스
- 북한살둘레길
- 재택근무
- 브런치작가되기
- 리얼하다
- 캐치마인드
- 프래그먼트
- 소프시스
- 끝말잇기
- 목적 중심 리더십
- 자취필수템
- 어떻게 나답게 살 것인가
- 슬기로운 온라인 게임
- T자형인재
- 소프시스 밤부 좌식 엑슬 테이블
- 한달브런치북만들기
- 안드로이드
- 테트리스
- Today
- Total
정상에서 IT를 외치다
[리엑티브 연습] concat, zip (네트워크 통신 예제) 본문
안녕하세요. 블랙진입니다.
리엑티브 연습 포스팅입니다.
여러 옵저버블의 데이터를 이터러밍 없이 발행해 줍니다. 즉 순서를 보장해 주는 오퍼레이터 입니다.
언제 사용할까요?
여러 API를 통신했을 때 순차적으로 처리가 필요한 경우에 사용합니다. 한 예로 사용자 정보를 가져오고 가져온 정보를 사용해 두번 째 api를 통신해야 되는 상황에서 사용하면 좋습니다.(다시 생각해보니 이 상황에서는 concatMap이 더 어울릴 것 같네요 ㅎㅎ)
예제
val temp1 = true
val temp2 = "BlackJin"
val temp3 = arrayOf(1,2,3,4,5)
val api1 = Single.just(temp1).delay(300, TimeUnit.MILLISECONDS) // 300ms 후 boolean을 반환하는 통신
val api2 = Single.just(temp2).delay(100, TimeUnit.MILLISECONDS) // 100ms 후 String 을 반환하는 통신val api3 = Single.just(temp3).delay(600, TimeUnit.MILLISECONDS) // 600ms 후 배열을 반환하는 통신
val start = System.currentTimeMillis() // 통신 시간 측정을 위한 변수
3개의 통신 예제가 있습니다. 각각의 딜레이는 300ms, 100ms, 600ms를 가지고 있죠? 이 예제 API를 가지고 테스트를 진행해 보겠습니다.
1. api1, api2 통신
Single.concat(api1, api2)
.subscribe({
println("${System.currentTimeMillis() - start} : $it")
}){
println(it.message)
}
concat 연산자는 통신의 순서를 보장해 줍니다.
[결과]
388 : true
488 : BlackJin
1. boolean를 반환하는 api1은 300ms가 걸리므로 388ms 에 true를 반환합니다.
2. String을 반환하는 api2는 100ms가 걸리는데 api1이 동작되고 나서 진행되기 때문에 488ms(388 + 100) 에 BlackJin을 반환했습니다.
2. api1, api2, api3 통신
Single.concat(api1, api2, api3)
.subscribe({
println("${System.currentTimeMillis() - start} : $it")
}){
println(it.message)
}
이번에는 600ms가 걸리는 api3 추가해 보겠습니다.
[결과]
395 : true
496 : BlackJin
1100 : [Ljava.lang.Integer;@690bc184
1. boolean를 반환하는 api1은 300ms가 걸리므로 395ms 에 true를 반환합니다.
2. String을 반환하는 api2는 100ms가 걸리는데 api1이 동작되고 나서 진행되기 때문에 496ms(395 + 101) 지난 후에 BlackJin을 반환했습니다.
3. Array를 반환하는 api3는 600ms가 걸리는데 api1, api2가 모두 동작되고 진행되기 때문에 1100ms(496 + 604) 지난 후에 Array를 반환했습니다.
여러 옵저버블의 결과를 합쳐서 하나의 데이터를 발행합니다. 이때 기준이 되는 시간은 가장 긴 옵저버블입니다.
언제 사용할까요?
여러 API를 동시에 통신하여 하나의 결과로 합쳐줄 때 사용하면 됩니다. 만일 zip을 사용하지 않으면 통신이 끝나는 시점이 모두 다르고 일부 통신은 연결중에 실패 할 수도 있습니다. 그러면 멀티 스레딩 환경에서 데이터의 동기화가 잘 이뤄지지 않고 어떤 사이드 이펙트가 발생할지 알 수 없는 상황이 됩니다.
예제
1. api1, api2 통신
Single.zip(
api1,
api2,
BiFunction<Boolean, String, String>
{ t1, t2 -> "$t1 $t2" }
)
.subscribe({
println("${System.currentTimeMillis() - start} : $it")
}) {
println(it.message)
}
[결과]
323 : true BlackJin
api1(delay: 300ms)과 api2(delay: 100ms) 중에서 api1의 통신이 끝난 시점(323ms)에 데이터가 발행 됨을 확인할 수 있습니다.
1. api1, api2, api3 통신
Single.zip(
api1,
api2,
api3,
Function3<Boolean, String, Array<Int>, String>
{ t1, t2, t3 -> "$t1 $t2 $t3" }
)
.subscribe({
println("${System.currentTimeMillis() - start} : $it")
}) {
println(it.message)
}
[결과]
626 : true BlackJin [Ljava.lang.Integer;@51c02284
api1(delay: 300ms), api2(delay: 100ms), api3(delay: 600) 중에서 api3의 통신이 끝난 시점(626ms)에 데이터가 발행 됨을 확인할 수 있습니다.
'안드로이드' 카테고리의 다른 글
[Android, Spinner] 스피너 기본 사용법부터 커스텀 까지! (3) | 2019.07.15 |
---|---|
[Android, Context] Context 넌 무엇이더냐? (2) | 2019.07.02 |
[리엑티브 연습] flatMap, concatMap, switchMap (1) | 2019.06.25 |
[리엑티브 연습] AsyncSubject, BehaviorSubject, PublishSubject, ReplaySubject (0) | 2019.06.25 |
[리엑티브 연습] Observable, Single, Maybe, Completable (0) | 2019.06.25 |