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()메소드가 호출됩니다.
| @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 이벤트가 발생할 때 에러가 발생했다고 알려줍니다.
댓글