본문 바로가기

프로그래밍/RxJava

[RxJava-3] 데이터 발행자(Data Source) : Observable 과 Single, Maybe, Completable

Observable 과 비슷한 데이터 소스에는 Single, Maybe, Completable 이 있습니다.

Flowable 이라는 것도 있지만 그건 나중에 알아보도록 할겠습니다.

 

Observable 이라는  데이터 소스를 구독했을 경우 구독을 해지하기 전까지는 Observable 발행하는 모든 데이터를 받을 수 있습니다. 하지만 안드로이드에서 주로 사용하는 API 통신의 경우 단발성 소통이 대부분이고, 이런 것에서 Observable 을 사용한다면 자원이 낭비됩니다.

이때 효율적으로 한번 데이터를 받으면 자동으로 구독해지, 종료시키는 데이터 소스가 Single, Maybe, Completable 입니다.

 

 

Observable 은 데이터가 발행되면 3가지 형태로 데이터를 받습니다.

public interface Emitter<T> {

    /**
     * Signal a normal value.
     * @param value the value to signal, not null
     */
    void onNext(@NonNull T value);

    /**
     * Signal a Throwable exception.
     * @param error the Throwable to signal, not null
     */
    void onError(@NonNull Throwable error);

    /**
     * Signal a completion.
     */
    void onComplete();
}

- onNext : 데이터를 수신받는다.

- onError : 오류 발생시 Exception 을 수신받는다.

- onComplete : 데이터 발행이 완료되었음을 수신받는다.

 

onNext 를 통해 데이터 발행이 완료될 때까지 데이터를 수신받습니다.

 

 

 

Single 은 데이터가 발행되면 2가지 형태로 데이터를 수신하고, 데이터 발생과 동시에 종료됩니다. 

public interface SingleEmitter<T> {

    /**
     * Signal a success value.
     * @param t the value, not null
     */
    void onSuccess(@NonNull T t);

    /**
     * Signal an exception.
     * @param t the exception, not null
     */
    void onError(@NonNull Throwable t);

    /**
     * 코드 중략
     */
}

- onSuccess : 데이터 발행 및 수신 성공

- onError : 데이터 발행 또는 수신 실패

 

데이터를 수신 성공하던, 실패하던 데이터 발생과 동시에 종료됩니다.

일반적인 API 통신의 경우에는 특정한 API 를 호출하고, 데이터를 딱 한번만 받고 종료하기 때문에

API 호출시에는 데이터 수신이 성공했는지, 실패했는지를 파악하는 데이터 소스 형태가 적합한 것 같습니다.

 

 

Maybe 의 경우에는 3가지 형태로 데이터를 수신하고, 데이터 발생과 동시에 종료됩니다. 
Single 과 비교하여 하나의 함수가 추가되었습니다. 

public interface MaybeEmitter<T> {

    /**
     * Signal a success value.
     * @param t the value, not null
     */
    void onSuccess(@NonNull T t);

    /**
     * Signal an exception.
     * @param t the exception, not null
     */
    void onError(@NonNull Throwable t);

    /**
     * Signal the completion.
     */
    void onComplete();

    /**
     * 코드 중략
     */
 }

 

- onSuccess : 데이터 발행 및 수신 성공

- onError : 데이터 발행 또는 수신 실패

- onComplete : 데이터 발행이 완료되었을 경우 (성공되었을때는 여기로 떨어지지 않음) 

 

Maybe 는 데이터가 있거나 없을때 사용합니다.

예를 들어 Room Database 에서 User Table 의 userId 를 가져오는 쿼리를 실행한다고 합시다.

앱 시작 직후 해당 쿼리를 실행한다고 했을 때, 앱을 처음 설치한 사용자의 경우 User Table 의 userId 값이 없습니다.

이때 Single 을 사용하여 쿼리를 호출할 경우 Error 가 발생합니다. 왜냐하면 데이터가 없기 때문이죠.

 

이럴 때 Maybe 를 사용합니다. 

 

 

Completable 은 2가지 형태로 데이터를 수신하고, 데이터 발생과 동시에 종료됩니다. 

public interface CompletableEmitter {

    /**
     * Signal the completion.
     */
    void onComplete();

    /**
     * Signal an exception.
     * @param t the exception, not null
     */
    void onError(@NonNull Throwable t);

    /**
     * 코드 생략
     */
}

- onComplete : 데이터 발생 완료

- onError : 데이터 발행 또는 수신 오류

 

Completable 은 데이터가 발행이 완료되었을 경우 onComplete 를 호출하고, 실패했을 경우 onError 함수가 호출됩니다. 

데이터를 발행한 후 처리할 데이터가 없을 경우 사용합니다.

처리할 데이터가 없다는 의미는, API 통신으로 예를 들면, 

 

일반적인 API 에서는 POST 를 보냈을 경우 해당 request 가 제대로 동작했는지 response 값을 받고, 응답받은 결과에 따라 앱 내에서 처리를 분기해줍니다.

{
   'result' : true, // or false
   'message' : "success" // or "failure"
}

 

하지만 일부 API 경우에는 응답값이 없는 경우도 있습니다. 

이럴 경우에는 굳이 응답 값을 받을 필요가 없죠. 이럴 때 Completable 을 사용합니다.

또는 Database 에 데이터를 update 했을 경우 돌아오는 응답이 없습니다. 이때도 Completable 을 사용합니다.

 

 

 

코드를 예시로 들어서 설명하면 좋았을 것 같네요.

조금 더 보충해오겠습니다.