If we don't use Rx but model asynchronous systems, that probably means our code is full of state machines and transient states that we need to simulate instead of abstracting away.
만약 우리가 Rx를 사용하지 않고 비동기 시스템을 모델링한다면,
그것은 아마도 우리의 코드가 추상화하는 대신 시뮬레이션해야 하는 상태 기계와 일시적인 상태로 가득 차 있다는 것을 의미할 것이다.
Rx를 사용하지 않은 비동기시스템을 구현하게 될경우에 상태관리나 상태전환에 대한 케이스를 하나하나 관리해주어야하고 코드양이 많아질수록 관리해야하는 상태 및 상태전환이 많아짐에 따라서 코드의 복잡성이 증가되며
설계와 유지보수가 어려워지고 문제발생시의 원인추적의 어려움이 높아진다.
허나 RxSwift를 사용함으로써
상태를 직접 관리하지 않고 이벤트 스트림으로
추상화 해서 사용한다는것이 포인트이고
흐름으로 표현되기에 전환과정이 명확하게 드러난다.
Here is a sequence of numbers: 여기에 숫자들의 시퀀스
--1--2--3--4--5--6--| // terminates normally
정상적으로 종료
Another sequence, with characters: 다른시퀀스 char 과 함께있는
--a--b--a--a--a---d---X // terminates with error
오류로 종료
Some sequences are finite while others are infinite, like a sequence of button taps:
어떤 시퀀스들은 유한하지만 다른시퀀스는 무한합니다. 마치 버튼이 눌리는것과 같이
---tap-tap-------tap--->
무한히 지속
These are called marble diagrams. There are more marble diagrams at rxmarbles.com
이런것들을 마블 다이어그램이라고 불리우고 링크에 더 많은 마블다이어그램이 있습니다.
If we were to specify sequence grammar as a regular expression(Regex) it would look like:
next* (error | completed)?
만약 우리가 시퀀스 문법을 정규표현식으로 명시한다면 그것은 next* (error | completed)? 것처럼 보일것입니다.
This describes the following:
- **Sequences can have 0 or more elements.**
- **Once an `error` or `completed` event is received, the sequence cannot produce any other element.**
Sequences in Rx are described by a push interface (aka callback).
이것이 의미하는바는
시퀀스는 0개 이상의 요소를 가질 수 있습니다 ,
“시퀀스가 error 또는 completed 이벤트를 수신하면, 더 이상 다른 요소를 방출할 수 없습니다.”
→ “Rx에서의 시퀀스는 푸시 인터페이스(콜백이라고도 함)에 의해 설명됩니다.”
콜백: 프로그래밍에서의 콜백은 주로 함수나 메서드를 파라미터로 전달하여 특정 시점이나 조건에 맞춰 호출되도록 하는 것을 의미합니다. 참조링크
next* | (error | completed)? |
- *는 0회 이상 반복을 의미합니다. - next는 시퀀스가 요소를 방출할 때의 onNext 이벤트를 의미 - 시퀀스는 0번 또는 여러 번요소를 방출할 수 있다는 뜻입니다. - next* 부분은 시퀀스가 0번 또는 여러 번의 onNext 이벤트를 방출할 수 있음을 나타냅니다. eg) 요소가 없을 수도 있고, 10개 이상 방출할 수도 있습니다. |
- |는 “또는”을 의미합니다. - error는 onError 이벤트로, 시퀀스가 에러로 종료되었음을 나타냅니다. - completed는 onCompleted 이벤트로, 시퀀스가 정상적으로 완료되었음을 나타냅니다. - ?는 0회 또는 1회만 발생할 수 있음을 의미합니다. - 즉, 시퀀스는 종료 이벤트로 onError 또는 onCompleted 중 하나만 발생할 수 있다**는 뜻입니다. - (error | completed)? 부분은 onError나 onCompleted 이벤트가 발생하면 시퀀스가 종료됨을 나타냅니다. - 종료 이벤트가 발생한 후에는 더 이상 다른 이벤트(onNext 포함)를 방출할 수 없습니다. |
eg)
1. 요소 없이 완료되는 시퀀스
2. 요소를 방출한 후 완료되는 시퀀스
3. 요소를 방출하다가 에러로 종료되는 시퀀스
4.요소 없이 에러로 종료되는 시퀀스
enum Event<Element> {
case next(Element) // next element of a sequence
case error(Swift.Error) // sequence failed with error
case completed // sequence terminated successfully
}
class Observable<Element> {
func subscribe(_ observer: Observer<Element>) -> Disposable
}
protocol ObserverType {
func on(_ event: Event<Element>)
}
When a sequence sends the `completed` or `error` event all internal resources that compute sequence elements will be freed.
“To cancel production of sequence elements and free resources immediately, call dispose on the returned subscription.”
시퀀스가 completed 또는 error 이벤트를 보낼 때, 시퀀스 요소를 계산하는 데 사용된 모든 내부 리소스가 해제됩니다.
시퀀스 요소의 생성을 즉시 중단하고 리소스를 해제하려면 반환된 구독(subscription) 객체에서 dispose를 호출해야 합니다.
“If a sequence terminates in finite time, not calling dispose or not using disposed(by: disposeBag) won’t cause any permanent resource leaks. However, those resources will be used until the sequence completes, either by finishing production of elements or returning an error.”
시퀀스가 유한한 시간 내에 종료된다면,
dispose를 호출하지 않거나 disposed(by: disposeBag)를 사용하지 않아도 영구적인 리소스 누수는 발생하지 않습니다.
하지만, 시퀀스가 요소 생성을 완료하거나 에러를 반환하여 종료할 때까지 해당 리소스는 계속 사용됩니다.
If a sequence does not terminate on its own, such as with a series of button taps, resources will be allocated permanently unless dispose is called manually, automatically inside of a disposeBag, with the takeUntil operator, or in some other way.”
시퀀스가 자체적으로 종료되지 않는 경우(예: 버튼 클릭 이벤트 시퀀스), dispose를 수동으로 호출하거나, DisposeBag 내부에서 자동으로 처리하거나, takeUntil 연산자를 사용하는 등의 방법으로 정리하지 않으면 리소스가 영구적으로 할당됩니다.
“Using dispose bags or takeUntil operator is a robust way of making sure resources are cleaned up. We recommend using them in production even if the sequences will terminate in finite time.”
“If you are curious why Swift.Error isn’t generic, you can find the explanation here.”
DisposeBag이나 takeUntil 연산자를 사용하는 것은 리소스를 정리하는 확실한 방법입니다. 유한 시간 내에 종료되는 시퀀스라 하더라도, 프로덕션 환경에서는 이러한 방법들을 사용하는 것이 권장됩니다.
• Swift의 Error 타입이 왜 제네릭이 아닌지 궁금하다면, 여기에서 설명을 확인할 수 있습니다.
[RxSwift] Scheduler.2 (1) | 2024.12.16 |
---|---|
[RxSwift] Scheduler.1 (2) | 2024.12.12 |
[RxSwift] DesignRationale (3) | 2024.12.08 |
[RxSwift] Basic.1 (1) | 2024.11.28 |
[RxSwift] Obsevables aka sequence (1) | 2024.11.27 |