[RxSwift] Transforming Operators

나는 사과·2021년 4월 30일
0

RxSwift

목록 보기
7/8

RxSwift에서 연산자들 중에서 중요한 연산자라고 할 수 있는 변환 연산자(Transforming Operator)에 대해 정리해보려고 한다. 어제 정리한 필터링 연산자처럼 Swift 표준 라이브러리와 유사한 연산자들이 있다.

  1. .toArray()
    요소들을 묶어 Array로 변환한다.
let disposeBag = DisposeBag()

Observable
    .of(1,2,3)
    .toArray()
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)

// [1,2,3]

위 코드처럼 1,2,3 요소를 .toArray() 한 다음 출력하면 [1,2,3] 이 출력되어 나온다.

  1. .map
    이 연산자도 Swift에서 사용했던 map과 같다. 수식에 맞게 변환을 한 값을 리턴한다.
let disposeBag = DisposeBag()

Observable
    .of(1,2,3)
    .map{
        $0 * 2
    }
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 2
// 4
// 6

map에서 각 요소(1,2,3)에 *2 한 값을 반환하도록 수식을 넣어준 다음 출력하면 (2,4,6)이 출력된다.

  1. .enumerated
    어제 정리한 필터링 연산자에서 사용했던 방법처럼 똑같이 사용한다. 그럼 값과 값에 해당하는 인덱스를 리턴한다.

내부 Observable 변환

이 부분은 보면서도 조금 헷갈려서 다시 한번 정리하면서 이해해보려고 한다...

  1. .flatMap
    observerable안에 있는 observable을 다루기 위해서 사용한다. 그림을 먼저 보면

    첫 째줄 Observerable의 (01,02,03)요소가 .flatMap을 통해서 새로운 Observable을 생성한다. 그 다음 최종적으로 각 요소의 Observable을 합친 마지막줄Observable을 생성한다.
    코드를 보게 되면...
struct Item{
    var price: BehaviorSubject<Int> // 가장 최신값을 알고싶을 때 사용
}

let disposeBag = DisposeBag()

let icecream = Item(price: BehaviorSubject(value: 1000))
let snack = Item(price: BehaviorSubject(value: 500))

// Observable 안에 Observable이 존재
let buyingList = PublishSubject<Item>()

buyingList
    .flatMap{
        $0.price
    }
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)

buyingList.onNext(icecream)
icecream.price.onNext(1500)
buyingList.onNext(snack)

// 1000
// 1500
// 500

먼저 BehaviorSubject를 사용해서 가장 최신 값을 알아내려고 했고 이를 프로퍼티로 갖는 Item 구조체를 정의했다. 그 다음 icecreamsnack 상수에 구조체 인스턴스를 할당하고 각각의 인스턴스가 갖는 초기값은 1000과 500 이다.
buyingList상수에 PublishSubject를 할당하는데 PublishSubject에 들어가는 타입이 Item구조체다. 그럼 Subject(buyingList 상수)안에 Subject(price 변수) 들어가는 모습을 볼 수 있다. 이 flatMap에서는 단순히 값 변환없이 그냥 전달하고 그것을 출력해준다. 그래서 buyingListonNext이벤트가 발생할 때마다 값이 출력되는 모습을 볼 수 있습니다.

  1. .flatMapLatest
    이 연산자는 말보다는 코드로 이해하는게 더 빠른 것 같아서 바로 코드로 넘어가도록 하겠습니다.
    struct Item{
       var price: BehaviorSubject<Int> 
    }

let disposeBag = DisposeBag()

let icecream = Item(price: BehaviorSubject(value: 1000))
let snack = Item(price: BehaviorSubject(value: 500))

let buyingList = PublishSubject()

buyingList
.flatMapLatest{
$0.price
}
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)

buyingList.onNext(icecream)
buyingList.onNext(snack)
icecream.price.onNext(1500)

// 1000
// 500

`flatMap`과 같은 코드에서 `flatMapLatest`로만 변경했다. 그러니 출력이 1000과 500만 발생했다. 왜그러냐면! `flatMapLatest`는 `icecream` Observable과 `snack` Observable이 존재하는데 `buyingList` 	Observable에 `icecream`의 값을 전달하면 `icream` Observable로 전환된다. 그래서 1000이 출력이 된다. 그 다음 똑같이 `snack`의 값을 `buyingList`에 전달하면 `snack` Observable로 전환이 된다. 가장 최신의 Observable로 전환된다는 말이다. 그래서 500이 출력이 된다.
그 다음 원래 `icecream` Observable에 1500을 전달했지만 값이 출력이 되지 않았다. 그 이유는 가장 최신의 Observable은 `snack` Observable이기 때문에 다른 Observable에서 방출된 이벤트 경우는 무시된다. 그래서 출력이 되지 않은 것 이다. 

이 연산자는 네트워킹 조작에서 많이 사용된다고 한다.

0개의 댓글