Aaron
286
2018-11-08 22:53:59
5
161

RxJava에서 doOnXXX 계열의 연산자는 왜 존재하는 건가요?


"RxJava 프로그래밍" 이란 책을 보고 있는데,

doOnNext, doOnComplete, doOnError 이런 연산자를 사용해서 로그를 찍더라고요?

그런데 subscribe, onComplete, onError에서 로그 찍는거랑 무슨 차이가 있는 건가요??

우선 실제로 찍어본 로그를 보면 차이를 느끼기 힘듭니다...


책에는...


"원래 함수형 프로그래밍은 함수의 부수 효과를 없도록 하는 것이 원칙이지만 doOnXXX() 계열 함수는 오히려 부수 효과를 일으켜서 내가 작성하는 코드가 문제없는지 알아볼 수 있게 합니다."


라고 적혀있는데...

여기서 말하는 부수 효과는 순수 함수 얘기할 때 나오는 그 부수 효과를 말하는 것 같고...

즉 순수 함수와 다르게 동일한 input에 대해 결과 값이 달라질 수 있다는 얘기인 것 같은데...

도통 이해가 안되네요 무슨 말인지;;;;;;


고수님들의 도움이 절실합니다 ㅠㅠ

0
0
  • 답변 5

  • Aaron
    286
    2018-11-08 23:03:18

    아 자문 자답입니다;;;

    onNext의 경우는 최종 consumer가 되는 거군요.

    반면 doOnNext는 업스트림 데이터를 다운스트림으로 내리는데 중간에 껴서 데이터를 살짝 보는 거고요.

    하지만 여전히 부수 효과에 대한 의미가 와닿지는 않네요 흠;;

        val orgs = listOf("1", "3", "5", "7", "9")
        Observable.fromIterable(orgs)
                .doOnNext { Log.d("doOnNext() - 1 : $it") }
                .map { Integer.parseInt(it) }
                .filter { it > 5 }
                .doOnNext { Log.d("doOnNext() - 2 : $it") }
                .doOnComplete { Log.d("doOnComplete()") }
                .doOnError { Log.e("doOnError(): ${it.message}") }
                .subscribe ({
                    Log.d("subscribe: $it")
                }, {
                    Log.e("onError: ${it.message}")
                }, {
                    Log.d("onComplete")
                })


    0
  • fender
    11k
    2018-11-08 23:29:55 작성 2018-11-08 23:30:47 수정됨

    Rx는 여러 '파이프 라인'을 조합해서 원하는 동작을 구현하는 개념입니다. 그리고 'subscribe'는 파이프라인의 마지막 단에서 호출하기 때문에, 가끔 다양하게 조합된 파이프의 각 부분을 'tap' 해서 값을 검사한다거나 로그를 기록하는 등의 작업이 필요한 경우 언급하신 메서드들을 유용하게 사용할 수 있습니다.

    아마도 예제에선 하나의 파이프만을 사용했기 때문에 그런 차이가 명확하게 느껴지지 않았던 듯 합니다.

    2
  • Aaron
    286
    2018-11-08 23:35:11

    fender 답변 감사합니다.

    혹시 부수 효과에 대해서는 어떻게 이해하면 좋을지 조언 부탁드려도 될까요 ㅠ

    0
  • fender
    11k
    2018-11-08 23:43:19 작성 2018-11-08 23:44:43 수정됨

    기본적으로 do*의 값은 파이프 안에 흐르는 내용에 영향을 주지 않습니다. 반면 그런 동작이 의미를 가지려면 파이프 외부에 어떤 영향을 행사해야하는데, 이는 예제와 같이 로그를 기록한다던가 하는 형태로 구현할 수 있습니다.

    '부수효과'의 의미는 여러가지로 이해할 수 있지만, 질문하신 맥락에선 Rx 파이프라인으로 구성된 실제 비즈니스 로직과 별개로, 로깅 같은 부차적인 효과를 발생시키는 모든 동작이라는 정도로 정의해도 무방할 것 같다는 생각입니다.

    예컨대 파이프의 값 자체를 변조하는 map과, 값에 어떠한 영향도 주지 않는 doOnNext의 차이를 생각해보면 이해에 도움이 될 지 모르겠습니다.

    2
  • Aaron
    286
    2018-11-08 23:47:03

    fender 오오오... 이해가 빡 됩니다! 정말 감사합니다.

    do 계열의 함수가 스트림에 영향을 주지 않기 때문에 부수 효과를 발생시킨다는 말이 더 이해가 안됐었는데요.

    "파이프 외부에 어떤 영향을 행사, 로그를 기록한다던가..." 이 말을 곱씹어 보니 머리가 번쩍하네요 ㅎㅎ

    정말 감사합니다~ 

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.