[RxJava] RxJava 이해하기 - 3. Single, Maybe, Completable



Single

개념

Single은 Observable의 변형된 형태이다. Observable과 비슷하지만, 여러 개의 데이터를 발행할 수 있는 Observable과 달리 Single은 한 개의 데이터(혹은 에러)만을 발행한다. 이전 포스트에서 말한 것처럼 Observable은 3가지 알림을 보내는 반면, Single은 onSuccess, onError 2가지의 알림을 보낸다.

  • onSuccess : 데이터 하나를 발행함과 동시에 종료
  • onError : 에러가 발생했음을 알림

img

Marble Diagram을 보면 Single은 데이터 하나를 발행함과 동시에 종료한다. 데이터 발행(onNext)과 완료(onCompleted)를 각각 알렸던 Observable과 달리 Single은 데이터 발행의 완료를 따로 알리지 않는다는 것이 특징이다.

따라서 Single은 결과를 단일값으로 가져오는 네트워크 통신 등에 유용하게 사용할 수 있다.


예제

간단하게 Single을 생성하는 예제를 만들어보겠다. 다른 연산자를 사용하는 방법과 Marble Diagram은 여기서 익히자.

가장 간단한 생성 방법은 정적 팩토리 함수(생성 연산자) just를 사용하는 것이다. Observable의 just를 사용할 때와 같은 방법으로 사용하면 된다.

// 1. Single.just() 사용
Single.just(1)
      .subscribe(System.out::println);

또 다른 생성 연산자인 create를 사용할 수도 있다.

// 2. Single.create() 사용
Single<Integer> createdSingle = Single.create(new SingleOnSubscribe<Integer>() {
    @Override
    public void subscribe(@NonNull SingleEmitter<Integer> emitter) throws Throwable {
        emitter.onSuccess(1);
    }
});
createdSingle.subscribe(System.out::println);

SingleEmitter<T>를 이용해 데이터를 발행하거나(onSuccess), 에러를 발생시킬 수 있다(onError).


Observable을 Single로 변환할 수도 있다. 단, 여러 데이터를 발행하는 Observable을 Single로 변환하면 컴파일에러가 발생한다는 사실에 주의하자.

// 3. fromObservable() 사용
Observable<Integer> observable = Observable.just(1);
Single.fromObservable(observable)
        .subscribe(System.out::println);

// 4. single() 사용
Observable.just(1)
        .single(0) //default value
        .subscribe(System.out::println);


Maybe

개념

Maybe도 Observable의 또 다른 형태이다. Maybe는 최대 데이터 하나를 발행할 수 있으며 추가로 데이터 없이도 완료할 수도 있다. Single에 onComplete가 추가된 형태로, 총 3가지 알림을 보낸다.

  • onSuccess : 데이터 하나를 발행함과 동시에 종료
  • onError : 에러가 발생했음을 알림
  • onComplete : 데이터 발행이 완료됐음을 알림

img


예제

Maybe도 Observable이나 Single과 같이 justcreate 연산자가 존재한다. 예제에서는 create를 통해 Maybe를 생성하였다.

Maybe는 최대 데이터 하나를 발행하므로 여러 개의 데이터를 전달해도 단 하나의 데이터만 발행되고 종료됨을 볼 수 있다. 또한 onSuccess가 데이터를 발행함과 동시에 종료되므로 이후에 나온 onComplete는 실행되지 않는다.

Maybe.create(new MaybeOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull MaybeEmitter<String> emitter) throws Throwable {
        emitter.onSuccess("Maybe 1");
        emitter.onSuccess("Maybe 2");
        emitter.onComplete();
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Throwable {
        System.out.println("onSuccess : "+s);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Throwable {

    }
}, new Action() {
    @Override
    public void run() throws Throwable {
        System.out.println("complete");
    }
});
[실행결과]
onSuccess : Maybe 1


Completable

개념

Completable은 데이터를 발행하는 Observable, Single, Maybe와 달리 데이터 발행의 완료/에러 신호만 보내는 특수한 형태이다. 따라서 데이터 발행의 완료를 알리는 onComplete와 에러 발생을 알리는 onError 2가지 알림을 보낸다.

  • onComplete : 데이터 발행이 완료됐음을 알림
  • onError : 에러가 발생했음을 알림

img


예제

Completable은 just 연산자가 없으므로 create 연산자나 fromXXX를 통해 생성한다.
예제를 보면, Completable은 데이터 없이 완료했다 / 에러가 발생했다는 결과만 전달하고 종료한다.

Completable completed = Completable.create(new CompletableOnSubscribe() {
    @Override
    public void subscribe(@NonNull CompletableEmitter emitter) throws Throwable {
        emitter.onComplete();
    }
});
completed.subscribe(new Action() {
    @Override
    public void run() throws Throwable {
        System.out.println("onComplete");
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Throwable {
        System.out.println("onError");
    }
});
[실행결과]
onComplete



:bookmark: REFERENCE
유동환, 박정준, 「RxJava 프로그래밍」, 한빛미디어
ReactiveX | Single
RxJava Github