본문 바로가기
Rx

Observable -10 (Single 클래스)

by 봄석 2018. 12. 23.

본 내용은 필자가 학습한 내용을 정리하는 내용입니다.

대부분 의 내용이 아래 책의 내용이므로 원서를 구매해서 직접보시는걸 추천드립니다!

RxJava 프로그래밍 리액티브 프로그래밍 기초부터 RxAndroid까지 한 번에

유동환 , 박정준 지음 | 한빛미디어 | 2017년 09월 04일 출간

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788968488658&orderClick=LAV&Kc=


Single 클래스

single 클래스는 RxJava 1.x 부터 존재하는 Observable의 특수한 형태입니다.

Observable 클래스는 데이터를 무한하게 발행할 수 있지만 Single 클래스는 오직 1개의 데이터만 발행하도록 한정합니다. 보통 결과가 유일한 서버 API를 호출할 때 유용하게 사용할 수 있습니다.



Single 클래스의 마블 다이어 그램

출처 - http://reactivex.io/documentation/ko/single.html#




1) Single 클래스의 시간 표시줄은 왼쪽에서 오른쪽으로 흐릅니다

2) 왼쪽 위 의 빨간별은 Single 클래스에서 발행한 결과 데이터입니다.

3) 왼쪽 아래의 빨간별, 이 Single 클래스는 filp()함수의 결과 값 입니다.

4) 오류가 발생하거나 Single이 비정상적으로 중단되는 경우는 X로 표기합니다.

[오른쪽 그림처럼]



중요한 것은 데이터 하나가 발행과 동시에 종료(onSuccess)된다는 점 입니다.

라이프 사이클 관점에서 보면 onNext()와 onComplete()함수가 onSuccess()함수로 통합된 것입니다. 따라서 Single 클래스의 라이프 사이클 함수는 onSuccess(T value) 함수와 onError()함수로 구성됩니다.





just()함수

single 클래스는 Observable과 거의 같은 방법으로 활용할 수 있습니다.


Single 클래스의 just함수 예제

Single<String> source= Single.just("Hello Single");

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





Observable 에서 Single 클래스 사용

Single은 Observable의 특수한 형태 이므로 Observable 에서 변환할 수 있습니다.


//1. 기존 Observable 에서 Single 객체로 변환하기
Observable<String> source=Observable.just("Hello Single");
Single.fromObservable(source).subscribe(System.out::println);
        
        
//2. single() 함수를 호출해 Single객체 생성하기.
Observable.just("Hello Single").single("default item").subscribe(System.out::println);
        
//3. first() 함수를 호출해 Single객체 생성하기
String[] color={"RED","GREEN","YELLOW"};
Observable.fromArray(color).first("default value").subscribe(System.out::println);
        
//4. empty Observable 에서 Single 객체 생성하기
Observable.empty()single("default value").subscribe(System.out::println);
        
//5.take()함수에서 single객체 생성하기
Observable.just(new Order("ORD-1"),new Order("ORD-2"))
.take(1)
.single(new Order("default order"))
.subscribe(System.out::println);



1) Single.fromObservable 을 활용한방법으로, 기존 Observable에서 첫번째 값을 발행하면
onSuccess 이벤트를 호출한 후 종료합니다.

2) Observable.just()통해서 생성된 Observable에 single() 함수를 호출합니다.
single() 함수는 default value를 인자로 갖습니다. Observable에서 값이 발행되지 않을 때도
인자로 넣은 기본값을 대신합니다.
3) 여러개의 데이터를 발행할 수 있는 Observable을 Single 객체로 변환하는 것입니다.
first()함수를 호출하면 Observable이 Single객체로 변환됩니다. 또한 하나 이상의 데이터를 
발행하더라도 첫 번째 데이터 발행 후 onSuccess 이벤트가 발생합니다.

4) empty()함수를 통해서 Single객체를 생성하는 방법입니다. 세번째 예처럼 첫번째 데이터 발행 후 onSuccess 이벤트가 발생한다는 점은 같습니다. 또한 두번째 예제처럼 Observable에서 값이
발행되지 않을 때도 기본 값을 갖는 Single 객체로 변환할 수 있습니다.

5) take()함수를 사용하는 예로, String 같은 기본 타입 뿐 아니라 사용자 정의 클래스(만들어둔)
Order 클래스 같은 것도 사용할 수 있습니다. subscribe()함수에는 System.out::println 이라는 
메소드 레퍼런스를 인자로 사용했는데 , Single 클래스에 넘겨진 Order객체의 toString()메소드가 호출됩니다.
1
2
3
4
@Override
    public String toString() { 
        return "Order ID: " + mId;
    }
cs





Single 클래를 생성할때 여러개의 값을 넣는다면??

앞에서는 Observable에서 Single객체를 생성할 때 데이터 하나만 발행하도록 보장했습니다.

그럼 실제로 just()함수에 여러개의 값을 넣으면 어떻게 될까요?


just()함수에 여러개 값 넣기


Single<String> source=Observable.just("Hello Single","Error").single("default item");
source.subscribe(System.out::println);



실행하게 되면 다음과 같은 에러가 발생하는데


Caused by: java.lang.IllegalArgumentException: Sequence contains more than one element!
    ... 10 more
Exception in thread "main" io.reactivex.exceptions.OnErrorNotImplementedException: Sequence contains more than one element!
    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
    at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:45)
    at io.reactivex.internal.operators.observable.ObservableSingleSingle$SingleElementObserver.onNext(ObservableSingleSingle.java:82)
    at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:107)
    at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36)
    at io.reactivex.Observable.subscribe(Observable.java:10901)


에러 메시지는 두 번째 값을 발행하면서 onNext 이벤트가 발생할 때 에러가 발생했다고 알려줍니다.




'Rx' 카테고리의 다른 글

Observable -12 ( 뜨거운 Observable)  (4) 2018.12.23
Observable -11 (Maybe 클래스)  (0) 2018.12.23
Observable -9 (fromPubilsher함수)  (4) 2018.12.23
Observable -8 (fromFuture함수)  (4) 2018.12.23
Observable -7 (fromCallable함수)  (3) 2018.12.23

댓글