RxJava flatMapCompletable 과 flatMap + ignoreElement 조합의 차이 이해하기
오늘은 RxJava에서 Completable을 방출해주도록 변환해주는 연산자인,
flatMapCompletable과 flatMap + ignoreElement 조합의 차이에 대해서 알아보겠습니다.
1. flatMapCompletable
flatMapCompletable은,
Single이나 Observable의 각 항목을 Completable로 변환합니다.
여기서 말하는 Completable은,
onComplete 혹은 onError 이벤트만 발생시키는,
Observable 을 말합니다.
Completable을 방출한다는 것은,
flatMap을 통해서 작업을 한 후,
반환되는 데이터가 필요하지 않다는 뜻 입니다.
이런 종류의 작업으로는 데이터베이스에 저장하는 경우를 생각해 볼 수 있겠네요.
Observable.just("작업A", "작업B", "작업C")
.flatMapCompletable(task -> doSomeDBTask(task))
.andThen(Completable.fromAction(() -> System.out.println("모든 작업 완료")))
.subscribe(
() -> System.out.println("Process finished"),
error -> System.err.println("Error: " + error.getMessage())
);
flatMapCompletable 을 사용하였으니,
구독하는 subscribe에서는,
onComlete나 onError에 대해서만 처리해 주면 됩니다.
2. flatMap + ignoreElement()
'flatMap + ignoreElement()'의 연산자 조합은
flatMapCompletable과 유사해 보이는데요.
이 두 연산자에 대해서 알아보겠습니다.
1-1. flatMap()
flatMap은 원본 Observable에서 흘러나온 아이템들을,
각각 새로운 Observable로 변환해주는 연산자인데요.
예를 들면 아래와 같습니다.
Observable.just(1, 2, 3)
.flatMap(i -> Observable.just(i * 10, i * 100))
.subscribe(System.out::println);
구독해서 얻은 출력값은 아래와 같은데요.
- 10, 100, 20, 200, 30, 300
상위의 스트림에서 흘러나온 아이템인,
1,2,3은 각각 새로운 Observable로 변화해서,
두 개의 값(i * 10, i *100)을 방출해 줍니다.
중첩없이, 하나의 스트림에서 각 항목에 대해 복잡한 변환이나 연산을 하도록 도와주지요.
1-2. ignoreElement()
ignoreElement()는 이 새로운 Observable의 데이터들을 무시하고,
Completable을 방출하므로,
완료와 에러만 신경쓰도록 해 줍니다.
3. flatMapCompletable과 flatMap + ignoreElement() 과의 차이
위에서 본 'flatMap + ignoreElement()'조합은,
flatMapCompletable과 유사해 보입니다.
flatMap을 한 것과, ignoreElement()를 사용해 Completable을 방출한다는 점에서 말이지요.
둘은 어떤 차이가 있는지 표로 비교해 볼까요?
flatMapCompletable | flatMap + ignoreElement |
직접 Completable을 반환 | flatMap은 Observable을 반환하고, ignoreElement()가 이를 Completable로 변환 |
원본 Observable의 각 항목을, Completable로 변환 |
원본 Observable의 각 항목을, 일단 새로운 Observable로 변환한 후, 그 결과를 무시하고 Completable 방출 |
모든 Completable이 완료되면 전체 스트림이 완료 | 모든 내부 Observable이 완료되면 전체 스트림이 완료 |
큰 차이가 있다라기 보다는,
flatMapCompletable이 좀 더 직접적이다라고 할 수 있는데요.
flatMap + ignoreElement()가 중간 단계에서 Observable을 생성하므로,
약간의 오버헤드가 있을 수 있습니다.
하지만 복잡한 연산이 아니므로,
크게 차이가 난다라고 하기는 어려울 것 같습니다.