728x90
Reactive Introduce
Reactive Programming
Reactive Programming이란?
: 비동기적 데이터 흐름과 전달에 관한 프로그래밍 패러다임입니다.
이러한 Reactive Programming의 핵심은 모든 것을 비동기적인 데이터의 스트림으로 간주하고 다양한 방법을 통해서 비동기 이벤트를 처리하는 것입니다.
👩🏻💻 개발자
프로그래머가 특정 기능을 직접 정해서 실행되도록 처리하는 것이 아니라 시스템 이벤트가 발생했을 때 이를 알아서 처리할 수 있도록 하는 것을 말합니다.
- 시스템 이벤트가 발생했을 때 이를 알아서 처리할 수 있다?
- 즉, 메서드의 호출로 동작되는 것이 아니라 Observable 안에 데이터를 조회하고 변환하는 메커니즘을 작성하면 Observable이 이벤트를 발생시키면 Observer가 이를 감지하여 준비된 연산하여 결과를 반환합니다.
- 그렇기 때문에 알아서 처리된다고 볼 수 있습니다.
- 개발자들은 자신의 코드가 점진적으로 하나씩 작성된 순서에 따라서 실행/완료 되기를 기대하지만 ReativeX에서는 Observer에 의해 임의의 순서에 따라 병렬로 실행되고 나중에 결과가 반환되는 것을 확인할 수 있습니다.
👩🏻⚖️ 사용자
- 사용자의 입장에서는 Reactive Programming을 기반으로 작성한 프로그램을 사용할 때 실시간성을 갖는다고 느낄 수 있습니다.
- 프로그래머가 작성한 순서대로 동작되는 것이 아니라 사용자와 상호 작용하면서 그에 따라 화면/기능이 실시간으로 변하기 때문입니다.
- 예를 들어서 인스타그램에 특정 게시물에 좋아요를 누르면 페이지를 새로 고침 하지 않아도 바로 좋아요 카운트가 올라가는 것을 볼 수 있습니다.
- 이를 실현하기 위해서는
- 프로그램이 지속적으로 특정 값을 관찰해야 합니다.
- 값을 관찰하다가 변화가 나타나면 특정 연산이 이뤄져야 합니다.
🤔 콜백 함수로 비동기 처리를 할 수 있지 않나요?
물론 비동기 처리를 위해서 관찰이 아닌, 단순 콜백 함수를 사용할 수 있습니다.
하지만, 연속된 비동기 작업이 필요할 경우 콜백 지옥이 나타나게 되는 등의 구조가 복잡해지기 때문에 관찰 방식을 사용하는 것이 더 효율적입니다.
또, 이미 Swift에는 비동기 API(Notification, Delegate, Grand Central Dispatch(GCD), Closures) 가 존재하지만 부분별로 나눠 사용하기 어려우며, 데이터를 다 받고 난 후에 UI Update를 진행합니다.
반면 RxSwift는 데이터 변경을 관찰하고 있기 때문에, 개발자가 작성한 순서대로 작동하는 것이 아니라 사용자와 상호 작용하며 UI를 실시간으로 업데이트해줍니다.
Observable
Observable
- Rx에서는 모든 것이 데이터의 스트림이며 이를 Observable이라고 표현합니다.
- 모든 것은 데이터의 스트림이다.
- Rx는 이러한 Observable의 변화를 관찰하기 위해서 이를 구독(Subscribe)합니다.
- RxSwift는 크게 Observable과 Subscribe와의 관계로 이루어진 코드 프레임워크라고 할 수 있습니다.
- Observable이 이벤트를 방출하면 → 해당 Observable을 구독한 Subscriber가 Observable이 방출한 이벤트를 갖고 액션을 취하는 것이 Rx의 핵심 동작입니다.
- 그리고 이를 반응형 프로그래밍이라고 합니다.
- 반응형 프로그래밍?
- : 어떠한 값의 상태 변화에 따라서 액션을 취하는 프로그래밍을 말합니다.
- Observable은 특정 형태의 데이터의 스냅샷을 전달하는 일련의 이벤트들을 비동기적으로 생성합니다. 그리고 이를 Observer라는 것에 전달합니다.
- Observer는 Observable을 Subscribe합니다.
- 그러면 Observer는 Observable이 발행하는 아이템이나 일련의 시퀀스에 반응할 수 있게 됩니다.
- 이러한 패턴은 동시적인 작동이 가능하게 합니다.
- 왜냐하면 Observable이 아이템을 발행할 때까지 기다릴 필요 없이 특정 아이템이 발행되면 그 시점을 감시하는 관찰자를 Observer 내부에 두고 그 관찰자를 통해 발행 알림을 받으면 되기 때문입니다.
Marble Diagram
아래 보여지는 그림은 "마블 다이어그램"으로, Observable의 흐름과 전환을 그림으로 표현한 것입니다.
- 위의 왼쪽에서 오른쪽으로 향하는 화살표는 Observable의 타임라인입니다.
- 왼쪽에서 오른쪽으로 흐릅니다.
- 위의 화살표에 위치하는 아이템들은 Observable에 의해 발행되는 아이템들입니다.
- 아이템들과 함께 수직 직선으로 보이는 화살표는 Observable이 성공적으로 completed 이벤트를 발행했음을 의미합니다.
- 위에서 아래로 향하는 점선 화살표와 박스는 Observable에서 행해지는 특정한 변환을 의미합니다. 박스 안쪽에 적힌 텍스트로부터 이것이 어떤 변환인지 알 수 있습니다.
- 위의 이미지에서는 뒤집는 변환을 하는 것을 알 수 있습니다.
- 아래의 왼쪽에서 오른쪽으로 향하는 화살표는 Observable의 변환 결과입니다.
- 아이템들과 함께 엑스 표시로 보이는 화살표는 error를 의미합니다.
Observer 생성
Observer는 아래와 같은 메서드를 구현하고 사용합니다.
- onNext
- Observable이 아이템을 발행할 때마다 해당 메서드가 호출됩니다. 해당 메서드는 Observable이 발행하는 아이템을 파라미터로 전달받습니다.
- onError
- Observable에서 오류가 발생할 경우 호출됩니다.
- 해당 메서드가 호출되면 onNext 나 onCompleted는 더 이상 호출되지 않고 라이프사이클이 종료됩니다. 해당 메서드는 error 객체를 파라미터로 전달받습니다.
- onCompleted
- 성공적으로 오류 발생 없이 주어진 시퀀스를 모두 발행했다면 호출됩니다.
let one = 1
let two = 2
let three = 3
let observable = Observable.of(one, two, three) // 1
observable.subscribe( // 2
onNext: { (element) in // 3
print(element)
},
onCompleted: { // 4
print("끝!")
}
)
/*
1
2
3
끝!
*/
- of 메서드를 통해 Observable 객체를 생성합니다. 해당 객체는 one, two, three의 데이터 시퀀스를 보유하고 이를 순서대로 발행합니다.
- subscribe를 통해 Observable에 대한 Observer를 만들 수 있습니다.
- onNext 메서드로 발행된 값을 이용한 동작을 처리합니다.
- onCompleted 메서드로 completed에서 수행할 동작을 처리합니다.
- 즉, 오류 발생 없이 주어진 시퀀스가 모두 동작될 경우의 수행 동작을 처리합니다.
- 위의 예시에서 1, 2, 3의 데이터 stream이 성공적으로 진행되었기에 “끝!”이 출력된 것을 확인할 수 있습니다.
🤔 구독을 해제한다?
Rx의 구현체에는 Subscriber라는 특별한 인터페이스가 존재합니다. 이 인터페이스 내의 unsubscribe라는 메서드를 제공하여 현재 subscribe중인 Observer에 대한 subscribe를 해지할 수 있습니다.
연산자 체인을 통해 Observer가 구독중인 Observable들이 더 이상 발행되지 못하도록 체인 내 연결 링크는 끊어버립니다.
Hot Observable VS Cold Observable
(코드예시랑 같이 볼 것)
Observable에 따라서 event를 방출하는 시점이 다릅니다.
Hot Observable🔥은 구독 여부에 관계 없이 요소를 방출해주는 Observable,
Cold Observable🧊은 구독이 되어야지 비로서 요소가 방출이 되는 Observable 입니다.
- Hot Observable은 생성되자마자 데이터에 대한 발행을 시작합니다.
- 따라서 데이터 발행 중간부터 Observable을 subscribe할 수도 있습니다.
- Subject
- 반면 Cold Observable은 Observer가 구독할 때까지는 데이터를 발행하지 않습니다.
- 따라서 이를 subscribe한 Observer는 전체 데이터 시퀀스를 전달받습니다.
Observable의 다양한 Operators
- Observable과 Observser는 표준 Observer Pattern을 확장한 개념입니다.
- Rx가 유용한 진짜 이유는 다양한 Operators에 있습니다.
- Operator는 Observable이 발생하는 연속된 아이템들을 변환, 결합, 조작하는 기능을 가졌습니다. 이 Operator 들은 선언적인 방법을 통해서 연속적인 비동기 호출을 구성할 수 있는 방법을 제공합니다.
- 일반적인 비동기 시스템이 가진 중첩 콜백의 단점을 제거 했다는 것에 높은 평가를 받습니다.
- 대부분의 Operator들이 Observable 상에서 동작하고 Observable을 반환합니다.
- 그렇기 때문에 하나의 Observable에 대해 연속적으로 Operator를 적용하는 것을 가능하게 합니다.
- 이들은 초기 Observable로부터 순차적으로 처리됩니다.
Creating Observables : 새로운 Observable을 만드는 Operator들 입니다.
- Creator
- Defer
- Empty/Never/Throw
- From
- Interval
- Just
- Range
- Repeat
- repeatElement
Start- Timer
Transforming Observables : Observable이 emit한 아이템들을 변환하는 Operator들 입니다.
- ToArray
- Map
- Buffer
- Flatmap
- FlatMapLatest
- GroupBy
- Scan
- Window
Filtering Observables : 기존의 Observable에서 특정 조건에 맞는 아이템만 발행하는 Operator들입니다.
- Debounce
- DistinctUntilChanged
- ElementAt
- Filter
FirstLast- IgnoreElements
- Sample
- Skip
- SkipLast
- Take
- TakeLast
Combining Observables : 여러 개의 Observable들을 하나의 Observable로 만드는 Operator들입니다.
And/Then/When- CombindLatest
Join- Merge
- StartWith
- Switch
- Zip
Error Handling Operators : Observable로부터 오는 오류를 확인하고 복구할 수 있도록 도와주는 Operator들입니다.
- Catch
- Retry
Utility Operators : Observable과 함께 동작하는 서포트 역할의 Operators들입니다.
- Delay
- Do
Materialize/Dematerialize- ObserveOn
Serialize- Subscribe
- SubscribeOn
TimeInterval- Timeout
Timestamp- Using
Conditional and Boolean Operators : 하나 이상의 Observable 또는 Observable이 발행한 아이템을 평가하는 Operator들 입니다.
- All
- Amb
- Contains
- DefaultIfEmpty
- SequenceEqual
- SkipUntil
- Skipwhile
- TakeUntil
- TakeWhile
Mathematical and Aggregrate Operators : Observable이 발행하는 항목 전체를 대상으로 동작하는 Operator들입니다.
Average- Concat
- Count
- Max
- Min
- Reduce
- Sum
Converting Observables : Observable을 다른 객체나 자료 구조로 변환합니다.
- To
Connectable Observable Operators : 좀 더 세세한 조작이 가능한 Observable들입니다.
Connect- Publish
- Refcount
- Replay
Chaining Operators
대부분의 연산자들은 Observable 상에서 동작하고 Observable을 반환합니다.
- 그렇기 때문에 연산자들을 연달아 호출할 수 있는 연산자 체인을 제공합니다.
- 연산자 체인에서 각각의 연산자는 이전 연산자가 반환한 Observable을 기반으로 동작하며 동작에 따라 Observable을 변경합니다.
- 먼저 실행된 연산자가 반환한 Observable을 기반으로 다음 연산자가 동작하기 때문에 순서를 잘 고려해야 합니다.
'Swift > RxSwift' 카테고리의 다른 글
[RxSwift] Reactive Programming / Memory Leak (0) | 2023.01.31 |
---|---|
[🌱SeSAC] Rx복습, RxAlamofire/RxDataSource (0) | 2022.10.31 |
[🔥Rx뿌셔] Relay (0) | 2022.10.31 |
[🔥Rx뿌셔] Subject - Replay Subject (0) | 2022.10.31 |
[🔥Rx뿌셔] Subject - BehaviorSubject (0) | 2022.10.31 |