ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxSwift - Observable
    RxSwift 2021. 10. 30. 17:02

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 RxSwift의 Observable에 대해 학습해보겠습니다🧑🏻‍💻

     

    그동안 RxSwift를 공부하면서 너무 중구난방으로 블로깅도하고 학습한 경향이 있는것같아요.
    제가 RxSwift를 학습한지 얼마되지 않아서 체계가 없었나봅니다🥲
    그래서 이번 기회에 RxSwift를 체계적으로 차근차근 다시 학습해보려합니다!🙌


    그런 취지로 이번 특집의 첫타자는 Observable입니다.

    가장 중요하고 기본적으로 알고 있어야 다른것들의 학습이 병행될 수 있는 Observable!

    같이 알아보시죠🙋🏻‍♂️

    참고로 해당 학습 ReactiveX 공식문서들과 아래 링크를 통해 학습되었고 학습할 것입니다!

    https://github.com/fimuxd/RxSwift/blob/master/Lectures/02_Observables/Ch2.%20Observables.md

     

    GitHub - fimuxd/RxSwift: RxSwift를 스터디하는 공간

    RxSwift를 스터디하는 공간. Contribute to fimuxd/RxSwift development by creating an account on GitHub.

    github.com

    Observable란?

    Rx 세계에서는 Observer 즉 관찰자라고 하는것이 Observable을 subscribe(구독)합니다.

    그러면 Observable이 Emit(방출)하는 이벤트나 이벤트 시퀀스에 반응하는 구조입니다.

    즉 이 패턴으로 Observable이 이벤트를 방출할때까지 기다리거나 하지 않기에 비동기적 처리가 가능합니다.

    그래서 요약하자면 Observable은 비동기적으로 어떠한 이벤트나 값을 생성하여 방출하는 역할을 합니다.

    Marble Diagram

    앞으로 Rx 세계에서 Observable의 이벤트 흐름에 대해 잘 설명할 수 있는것이 요 마블 다이어그램입니다!

    시간 흐름에 따라 이벤트들의 값을 표기해주는 방식입니다.

    즉 Observable과 Observable의 변환을 나타내줍니다.

    앞으로 나올 참고할 이벤트 그림들은 다 마블 다이어그램을 가져옵니다!

    아래 사이트를 참고해보시면 좋습니다🙌

    https://rxmarbles.com

     

    RxMarbles: Interactive diagrams of Rx Observables

     

    rxmarbles.com

    Observable Life Cycle

    Observable의 생명주기에는 3가지 요소로 되어 있습니다.

    1. next

      next를 방출해 다음 이벤트를 방출할 수 있습니다.

    2. completed

      이벤트들이 다 방출되면 completed를 방출하며 종료시킵니다.

    3. error

      도중 에러가 발생하면 error를 방출하며 종료됩니다.

    Observable Create

    Observable을 생성하는 방법에는 여러가지가 있습니다.

    이를 각 종류마다 어떤 특성이 있는지 알아보겠습니다🙌

    1. of

     가변적인 단일요소 element를 가지는 Observable Sequence를 생성

    let observable = Observable<String>.of("green", "blue", "red")

    어레이가 아닌 String 타입입니다.

    어레이를 넣어주게 되도 해당 어레이는 단일요소가 됩니다.

    2. just

     이름에서도 느껴지듯이 딱 하나의 element를 가지는 Observable Sequence를 생성

    let observable = Observable<String>.just("Green")

    3. from

     of에서 어레이도 단일요소가 된다 했는데 from은 오로지 Array element만 받음

    let observable = Observable<String>.from(["green", "blue", "red"])

    4. empty

     element를 가지지않고 completed 이벤트를 방출

    let observable = Observable<Void>.empty()

    Observable은 타입을 꼭 정의해줘야함으로 해당 empty를 사용할때는 컴파일러가 타입추론을 할 수 없음으로 Void로 지정

    5. never

     empty와의 차이는 never는 이벤트도 방출하지 않음

    let observable = Observable<Any>.never()

    6. range

     Observable의 크기를 지정해주어 생성할 수 있음

    let observable = Observable<Int>.range(start: 1, count: 3)

    파라미터로는 시작 element인 1을 줄 수 있고 그 다음 몇개를 생성해줄지 count를 주어 생성해줍니다.

    7. repeatElement

     한번 방출하고 끝이 아닌 정해준 element를 지속적으로 emit해줌

    let observable = Observable<String>.repeatElement("Green")

    이러면 "Green" element를 계속 방출합니다.

    8. interval

     시간을 지정해줘 그 간격만큼 element를 방출

    let observable = Observable<Int>.interval(2, scheduler:MainScheduler.instance)

     

    해당 Observable을 통해 2초마다 특정한 이벤트를 방출할 수 있도록 해줍니다.

    9. create

    Observer에 직접적으로 이벤트를 방출

    Observable<Int>.create({ (observer) -> Disposable in
      observer.onNext("Green")
      observer.onNext("Blue")
            
      observer.onCompleted()
      return Disposables.create()
    })

    Observable 구독

    위의 Observable 생성을 통해 시퀀스들을 만들어주었다.

    이 시퀀스를 구독하고 실행할 수 있도록 해야한다.

    왜나하면 해당 생성된건 그냥 말그대로 시퀀스일뿐이고 어딘가에서 이 Observable을 구독해야 이벤트를 방출합니다.

    그전에는 아무 동작을 안합니다🚨

    그럼 구독을 할 수 있도록 해줘봅시다!

    subscribe()

    해당 키워드로 구독해줍니다. 딱 용어만 봐도 구독이죠?!

    let observable = Observable.of("Green", "Blue", "Red")
    
    observable.subscribe({ (event) in
      print(event)
    })
    
    // next("Green")
    // next("Blue")
    // next("Red")
    // completed

    위의 예시의 subscribe는 탈출 클로저로 String의 이벤트를 가지고 Disposable을 리턴해줍니다.

    각 요소들을 subscribe하여 next 이벤트로 방출하고 끝난 후 completed 이벤트를 방출해줬습니다.

    그런데 위의 주석을 보면 next이벤트까지 포함됩니다.

    그럼으로 아래와 같이 해당 값만 프린트해볼 수 있습니다.

    observable.subscribe { event in
      if let element = event.element {
        print(element)
      }
    }
    
    // Green
    // Blue
    // Red

    subscribe(onNext:)

    해당 위의 코드에서 next 이벤트들만 받고 나머지는 무시할때 쓰입니다.

    또한 위의 코드가 너무 지저분하기에 아래와 같이 축약될 수 있습니다!

    let observable = Observable.of("Green", "Blue", "Red")
    
    observable.subscribe(onNext: { (event) in
      print(event)
    })

    Disposing & Terminating

    1. dispose()

    구독을 수동적으로 취소해 Observable을 종료시킵니다.

    let observable = Observable.of("Green", "Blue", "Red")
    
    let names = observable.subscribe({ event in
      print(event)
    })
    
    names.dispose()

    해당 names의 dispose를 주어 구독을 취소하고 종료시켰습니다.

    이후 발생되는 이벤트들은 정지됩니다.

    2. DisposeBag()

    위와 같이 매번 dispose를 수동적으로 주면서 관리하면 귀찮아지겠죠?

    그럼으로 어느 한 가방에 담는다는 개념을 가져갈 수 있습니다.

    이러한 구독취소들을 한 바구니에 담아 관리할 수 있습니다.

    즉 DisposeBag 타입을 이용하는겁니다.

    DisposeBag은 할당 해제하려할때 dispose()를 호출하는 disposables를 가지고 있습니다.

    let disposeBag = DisposeBag()
    
    Observable.of("Green", "Blue", "Red")
      .subscribe({ (event) in 
        print(event)
      })
      .disposed(by: disposeBag)

    subscribe를 통해서 방출되는 값들은 disposeBag에 담아 한번에 처리해줍니다.

    Trait

    Observable을 알아봤으니 더 옵션으로 Trait도 알아보겠습니다.

    Trait은 Observable보다 적은 스코프의 Observable이라 생각하면 됩니다.

    Observable이라는 큰 집합안의 부분집합 정도로 생각하면 되려나🤔

    무튼 이 Trait으로 가독성을 높일 수 있습니다.

    종류로는 3가지가 있습니다.

    1. Single

    싱글은 옵저버블의 특성인 존재하지 않는 범위에서 계속 임의적으로 연속된 이벤트를 방출하는것과 달리

    매번 하나의 값 혹은 에러 둘중 하나만 방출합니다.

    요 값들을 .success(value) / .error라 합니다.

    .success(value)는 next와 completed의 결합입니다.

    이 Single이 많이 사용되는 경우는 성공 혹은 실패의 명확한 프로세스이면서

    1회성 프로세스인 데이터 다운로드 및 로딩과 같은 상황이 있습니다.

    2. Maybe

    Single과 Completable을 결합한것으로 성공 혹은 실패를 방출하면서 값도 방출할 수 있습니다.

    즉, .success(value), .completed, .error를 가집니다.

    파일에서 어떤 값을 읽어들여올때 사용해볼 수 있습니다.

    3. Completable

    말그대로 완료인지 실패인지만 방출하고 이벤트나 값을 방출하진 않습니다.

    즉 .completed 혹은 .error를 가지는거죠.

    파일쓰기 및 연산 등 값이 없어도 되는 성공과 실패의 경우 사용됩니다.

    Debug

    debug 연산자로 Observable의 이벤트들을 디버깅해볼 수 있으며 유용하게 사용됩니다.

    observable
      .debug("Debug Test")			
      .subscribe()					
      .disposed(by: disposeBag)

    간단하게 요런식으로 디버깅을 해볼 수 있습니다.

     

    마무리

    자 이렇게 오늘은 RxSwift에서 가장 기초이지만 가장 중요한! Observable에 대해 알아봤습니다🙌

    처음 접하면 정말 어려운 개념이고 이해도 안되는게 당연한거에요😅

    다음 시간에는 Subject라는 개념에 대해 알아보도록 하겠습니다🙌

     

    [참고자료] 

    http://reactivex.io/documentation/observable.html

     

    ReactiveX - Observable

    Observable In ReactiveX an observer subscribes to an Observable. Then that observer reacts to whatever item or sequence of items the Observable emits. This pattern facilitates concurrent operations because it does not need to block while waiting for the Ob

    reactivex.io

    https://github.com/fimuxd/RxSwift/blob/master/Lectures/02_Observables/Ch2.%20Observables.md

     

    GitHub - fimuxd/RxSwift: RxSwift를 스터디하는 공간

    RxSwift를 스터디하는 공간. Contribute to fimuxd/RxSwift development by creating an account on GitHub.

    github.com

    https://jinshine.github.io/2019/01/02/RxSwift/2.Observable이란/

     

    [RxSwift] Observable이란 - (2) - jinShine

    Observable이란 observable, observable sequence, sequence라는 표현을 쓰는데 사실 다 같은 말입니다. 중요한것은 이벤트가 비동기적으로 생성하는 기능 이라는것이고, 계속해서 이벤트를 생성하는데 이러한

    jinshine.github.io

     

    'RxSwift' 카테고리의 다른 글

    RxSwift - Filtering Operators  (0) 2021.11.08
    RxSwift - Subject  (0) 2021.11.03
    RxSwift - Zip  (0) 2021.10.13
    RxSwift - Buffer & Window  (0) 2021.10.06
    RxSwfit - Debounce & Throttle  (0) 2021.10.02
Designed by Tistory.