[Unity] UniRX - 3 IObserver 메세지 종류
by Sugar0810UniRx에서 사용되는 이벤트 메시지는 이 3가지를 이용해 처리된다.
- OnNext : 일반적인 이벤트 발생 시 통지
- OnError : 스트림 처리 중 예외(Exception) 발생 시 통지
- OnComplete : 스트림 종료 통지
IObserver와 IObservable 인터페이스 클래스 소스 코드를 보면 위 도표와 똑같이 각각 3개, 1개의 메서드만 정의되어 있다.
using System;
namespace UniRx
{
public interface IObserver<T>
{
void OnNext(T value);
void OnError(Exception error);
void OnCompleted();
}
}
Subscribe 메서드는 이 메시지들 중 원하는 것만 받아서 처리할 수 있게 각 상황별로 오버로드 되어 있다.
Subscribe 오버로드 | 기능 |
Subscribe(IObserber observer) | 기본형 |
Subscribe() | 모든 메시지를 무시한다 |
Subscribe(Action onNext) | OnNext 만 처리 |
Subscribe(Action onNext, Action onError) | OnNext & OnError |
Subscribe(Action onNext, Action onCompleted) | OnNext & OnCompleted |
Subscribe(Action onNext, Action onError, Action onCompleted) | OnNext & OnError & OnCompleted |
.OnNext
var intTest = new Subject<int>();
intTest.Subscribe(x => Debug.Log(x));
intTest.OnNext(2);
intTest.OnNext(50);
intTest.OnNext(100);
// Result
2
50
100
- UniRx에서 이벤트를 통지할 때 대부분의 상황에서 사용됨
- 이 OnNext만 사용해도 큰 문제없음
- OnNext가 호출될 때마다 정수형 이벤트를 Subcribe에 통지해 준다.
.OnError
- 스트림 처리 중 예외(Exception)가 발생하면 통지
- 에러 처리가 필요 없다면 OnNext와 달리 생략해도 된다.
- OnError 메시지가 Subcribe에 도달한다면 이 스트림은 그 시점에서 바로 구독이 종료된다.
var stringSubject = new Subject<string>();
void Start()
{
// 문자열을 스트림 중간에서 정수로 변환한다
stringSubject
. Select(str => int.Parse( str )) // int 형이 아닌 경우 int.Parse 메소드에서 예외가 발생
. Subscribe(
// OnNext 시 처리
x => Debug.Log("성공 : " + x),
// OnError시 처리. 생략하면 예외 처리 안함
ex => Debug.Log("예외 : " + ex)
); //Subscribe의 오버로드 중 Subscribe(OnNext, OnError)
stringSubject.OnNext("1");
stringSubject.OnNext("2");
stringSubject.OnNext("Hello"); // 문자열을 넣으므로 Select 구문의 int.Parse에서 예외 발생
stringSubject.OnNext("4");
}
// Result
성공 : 1
성공 : 2
예외 : System.FormatException : Input string was not in the correct format
스트림을 처리하는 중에 예외가 발생하자 Subscribe에 OnError 메시지가 통지되고 스트림의 구독이 종료되어 이후에 발생한 OnNext("4")는 처리되지 않았다.
var stringSubject = new Subject<string>();
void Start()
{
// 문자열을 스트림 중간에서 정수로 변환한다
stringSubject
.Select(str => int.Parse(str)) // int 형이 아닌 경우 int.Parse 메소드에서 예외가 발생
.OnErrorRetry((FormatException ex) => // 예외 정보의 필터링 가능
{
Debug.Log("에외 발생하여 다시 실행");
})
.Subscribe(
// OnNext 시 처리
x => Debug.Log("성공 : " + x),
//OnError 시 처리. 생략하면 예외 처리 안함
ex => Debug.Log("예외 : " + ex)
); // Subscribe 의 오버로드 중 Subscribe(OnNext, OnError)
stringSubject.OnNext("1");
stringSubject.OnNext("2");
stringSubject.OnNext("Hello");
stringSubject.OnNext("4");
stringSubject.OnNext("5");
}
// Result
성공 : 1
성공 : 2
예외 발생하여 다시 실행
성공 : 4
성공 : 5
이전 예제와 달리 예외가 발생해도 마지막까지 Subscribe에 통지를 진행한다.
다른 점은 예외가 발생한 Select와 Subscribe 사이에 OnErrorRetry 가 추가된 점인데 이 OnErrorRetry는 예외를 중간에서 Catch 한 후 스트림을 재구축 (Subject에 IObserver를 다시 등록) 하여 구독을 계속 이어가게 해 준다.
이로 인해 Subscribe의 OnError 가 발생하지 않게 되는 것이다.
이 예외 처리와 관련한 몇 개의 오퍼레이터가 있다.
Operators | 기능 |
Retry | OnError 발생 시 다시 Subscribe 한다 |
Catch | OnError 발생 시 예외 처리 후 다른 스트림으로 대체한다 |
CatchIgnore | OnError 발생 시 예외 처리 후 OnError 를 무시하고 OnCompleted 로 대체한다 |
OnErrorRetry | OnError 발생 시 예외 처리 후 Subscribe 한다 (시간 지정 가능) |
.OnCompleted
- '스트림이 완료되었으므로 이후로는 메시지를 발행하지 않는다.'라는 사실을 통지하는 메시지
- OnError와 마찬가지로 Subscribe에 OnCompleted가 통지되면 해당 스트림은 바로 구독 종료된다.
- 이를 이용하여 스트림을 파기하려는 시점에 OnCompleted를 발행하여 구독을 종료시킬 수 있다.
- 이렇게 구독이 종료된 Subject는 재사용이 불가능하며 Subcribe를 호출해도 바로 OnCompleted가 발생
var subject = new Subject<int();
subject.Subscribe(
x => Debug.Log(x),
() => Debug.Log("OnCompleted")
); // ubscribe 의 오버로드 중 Subscribe(OnNext, OnCompleted)
subject.OnNext(1);
subject.OnNext(2);
subject.OnCompleted();
subject.OnNext(4);
subject.OnNext(5);
// Result
1
2
OnCompleted
📚 참고사이트
'⚙️ Programming > C# & Unity' 카테고리의 다른 글
[Unity] UniRX - 5 Operator (1) | 2023.01.16 |
---|---|
[Unity] UniRX - 4 IObservable의 Dispose와 스트림의 생명 주기 (0) | 2023.01.16 |
[Unity] UniRX - 2 Subject, Observable 사용법 (0) | 2023.01.16 |
[Unity] UniRX - 1 '비동기적 데이터 흐름' 처리 프로그래밍 라이브러리 개념 (0) | 2023.01.16 |
[Unity] DoTween과 코루틴을 이용한 스플래시 오프닝 (0) | 2023.01.16 |
블로그의 정보
Sugar
Sugar0810