본문 바로가기

안드로이드

안드로이드 RxJava #5 마블 다이어그램, RxJava 연산자-(생성)

 

안녕하세요

이번 시간에는 마블다이어그램 보는 방법과 RxJava 연산자에 대해 알아보겠습니다.

 

 

마블 다이어그램

 

1. Observable의 타임 라인, 왼쪽에서 오른쪽으로 시간이 흐름을 의미한다.

2. Observable이 순차적으로 발행하는 데이터를 의미한다.

3. Observable이 정상적으로 완료됨을 의미한다.

4. 점선과 박스는 Observable의 변형을 의미하며, 박스 안의 텍스트(filp)가 변형의 종류를 의미한다.

5. Observable의 변형 결과를 의미한다.

6. 만약 Observable이 정상적으로 종료되지 않았다면 X 표시와 함께 에러를 나타낸다.

 

 

안드로이드 RxJava #2에서 배운 create()를 마블 다이어그램으로 표현하면 다음과 같다.

Observable<String> source = Observable.create(emitter -> {
            emitter.onNext("빨간공");
            emitter.onNext("파란공");
            emitter.onComplete();

        });
        source.subscribe(System.out::println);

 

 

 

RxJava 연산자

크게 4종류의 연산자가 있다.

1. 생성하는 연산자

2. 변형하는 연산자

3. 필터링하는 연산자

4. 결합하는 연산자

 

오늘은 생성하는 연산자에 대해 알아보겠습니다.

 

defer

defer 연산자는 옵서버가 구독할 때까지 Observable의 생성을 지연시킨다. subscribe() 메서드를 호출할 때 Observable 아이템을 생성한다.

 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.KOREA);
        Observable<String> justSrc = Observable.just(
                sdf.format(System.currentTimeMillis())
        );
        Observable<String> deferSrc = Observable.defer(() ->
                Observable.just(sdf.format(System.currentTimeMillis()))
        );
        System.out.println("현재시각1 : " + sdf.format(System.currentTimeMillis()));

        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("현재시각2 : " + sdf.format(System.currentTimeMillis()));
        justSrc.subscribe(time ->
                System.out.println("justSrc : " + time)
        );
        deferSrc.subscribe(time ->
                System.out.println("deferSrc : " + time)
        );

 

실행하면 다음과 같은 결과를 볼 수 있다.

2022-11-07 14:53:06.953 31329-31329/com.psw.rxtest3 I/System.out: 현재 시각1 : 2022-11-07 05:53:06
2022-11-07 14:53:11.956 31329-31329/com.psw.rxtest3 I/System.out: 현재 시각2 : 2022-11-07 05:53:11
2022-11-07 14:53:11.960 31329-31329/com.psw.rxtest3 I/System.out: justSrc : 2022-11-07 05:53:06
2022-11-07 14:53:11.960 31329-31329/com.psw.rxtest3 I/System.out: deferSrc : 2022-11-07 05:53:11

현재 시각 1이 출력된 후 5초의 시간이 지나고 나머지 내용이 출력된다.

여기서 주목해야 할 점은 5초의 시간이 지나고 출력된 내용이다. just로 만든 Observable는 Observable가 생성되었을 때 값을 나타내고 defer로 만든 Observable는 구독을 한 시점의 값을 나타 낸다. 

즉 defer는 구독을 하기 전까지 아이템 발생을 하지 않는다.

구독하기 직전에 Observable을 생성하여 가장 최신의 아이템을 사용할 목적이라면 defer연산자를 이용해야 한다.

 

 

 

empty, never 

empty와 never 은 둘 다 아이템을 발행하지 않지만, onComplete() 호출 여부에 차이점이 있다.

 

	Observable.empty()
                .doOnTerminate(() -> System.out.println("empty 종료"))
                //.doOnComplete(()->System.out.println("empty test"))
                .subscribe();

        Observable.never()
                .doOnTerminate(() -> System.out.println("never 종료"))
                //.doOnComplete(()->System.out.println("never test"))
                .subscribe();

empty, never연산자 모두 아이템을 발행하지 않지만, empty는 정상적으로 스트림을 종료하고 never은 스트림을 종료시키지 않는다.

 

doOnTerminate 메서드의 콜백은 Observable이 종료될 때 onComplete()가 호출되는데 never에 경우 onComplete()가 호출되지 않는 것을 확인할 수 있다.

 

 

 

interval

 	Disposable disposable = Observable.interval(1, TimeUnit.SECONDS)
                .subscribe(System.out::println);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        disposable.dispose();

interval 연산자는 주어진 시간 간격으로 순서대로 정수를 발행하는 Observable을 생성한다.

무한히 아이템을 발행하므로 적절한 시기에 Disposable을 이용해 폐기하는 것이 좋다.

 

 

 

range

	Observable.range(2, 5)
  		.doOnComplete(()->System.out.println("doOnComplete"))
                .subscribe(System.out::println);

range 연산자는 특정 범위의 정수를 순서대로 발행한다.

interval과 비슷하지만 특정 범위의 아이템만 발행하고 아이템 발행이 끝나면 스트림을 종료시킨다.

 

 

 

timer

	Observable src = Observable.timer(5, TimeUnit.SECONDS);
        src.subscribe(item -> System.out.println("5초 뒤 실행"));

timer 연산자는 특정 시간 동안 지연시킨 뒤 아이템을 발행하고 종료한다.

구독한 시점부터 일정 시간이 지난 후 아이템을 발행한다.

 

 

 

다음 시간에는 변형하는 연산자에 대해 알아보겠습니다.

수고하셨습니다!

반응형