[RxSwift] 6-1. Operators ; Create

miori·2022년 2월 14일
0

RxSwiftBasic

목록 보기
13/29
post-thumbnail

RxSwift를 21일간 공부하는 루틴
"Rx를 기깔나게 쓰는 신입개발자 도전" 시작 🚀


RxSwift에서 제공하는 operator중 먼저, 생성에 관련된 operator를 정리해보겠다.

Overview

각각의 create operator 의 특징을 고려해 아래와 같이 언제 사용해야 적절할지에 대해 고민해보았다.
그리고 그 고민의 결과를 플로우차트로 나타내보았다.

flow-chart

이제 하나하나씩 자세히 정리해보도록하겠다.

create

앞선 정리글에서 여러번 create 연산자를 사용한 적이 있다.
create 를 사용한다면, observable을 직접 구현할 수 있다.

Observable<String>.create { observer in
    observer.onNext("🏋🏻‍♀️")
    observer.onCompleted()
    //observer.onError(Err.error)
    return Disposables.create()
}.subscribe(
    onNext: { print("Next",$0) },
    onError: { print("Error",$0) },
    onCompleted: { print("Completed") },
    onDisposed: { print("Disposed") }
).disposed(by: disposeBag)

물론 create를 사용해 이벤트를 방출해 줄 수 있지만, 구현 해야하는 상황에 맞는 연산자를 잘 활용한다면 더욱 효율적이라고 생각한다.

create 이후에 정리할 연산자는 파라미터로 전달된 요소를 방출한다.

range

range는 공차가 1인 등차수열이다.
range는 방출시 조건을 파라미터로 받지않는다.

정의

range 의 definition을 보면 다음과 같다.
range Def

파라미터로 start, count, scheduler를 받는데 이때 scheduler는 초기값이 지정되어있어서, start와 count값을 필수로 넘겨줘야한다.

코드

//MARK: Range
Observable.range(start: 0, count: 5)
    .subscribe { print("range : \($0)")}
    .disposed(by: disposeBag)

다음과 같이 생성해 줄 수 있다.
start는 시작값이고, count는 몇개를 방출할 지에 대한 파라미터이다.
따라서 0부터 1씩 증가하는 시퀀스를 방출하는데 이때 5개를 방출 한다.
output은 다음과 같다.

range : next(0)
range : next(1)
range : next(2)
range : next(3)
range : next(4)
range : completed

그렇다면, 감소하는 시퀀스를 만들고 싶거나 공차가 1이 아닌 시퀀스를 만들고 싶을 때는 어떻게 해야할까에 대한 고민을 해결해 주는 연산자가 generate이다.

generate 의 경우, 파라미터로 받는 condition을 통해 조건을 추가해 줄 수 있고, iterate를 통해 step (공차)을 정해 줄 수 있다.

정의

generate

만약, 5가 시작값이고 2씩 감소하는 시퀀스인데, 0보다 클때 까지만 방출 하고 싶다면, 다음과 같이 generate를 활용해 구현할 수 있다.

코드

//MARK: generate
Observable.generate(initialState: 5, condition: { $0 >= 0 }, iterate: { $0 - 2 })
    .subscribe { print("generate : \($0)")}
    .disposed(by: disposeBag)

initialState 를 통해 5 부터 시작함을 알 수 있다.
그다음 파라미터인 condition 을 보면 bool을 반환하고 true 일때만 next 이벤트를 방출해준다. 마지막 파라미터인 iterate는 step (우리가 알고있는 등차수열의 공차와 비슷한 역할)을 정해줄 수 있다.

위 코드를 실행 했을 때 다음과 같은 output을 얻게된다.

generate : next(5)
generate : next(3)
generate : next(1)
generate : completed

그렇다면 만약 동일한 요소만을 방출하고 싶을때는 어떤 연산자를 쓸 수 있을까?
repeat 를 사용할 수 있다.

repeat

repeat 의 경우 플로우 차트를 다시 보면, 조건을 추가할 것인가에 yes 에 해당된다. 물론 파라미터로 조건을 받지는 않지만 repeat 를 사용하면 무한루프에 빠질 수 있다. 따라서 take연산자를 활용해 몇개를 방출할지, 방출되는 요소의 수를 정해 줄 수 있다.

코드

//MARK: Repeat
Observable.repeatElement(0)
    .take(3)
    .subscribe{ print("repeat : \($0)")}
    .disposed(by: disposeBag)

이 코드를 실행 시킨다면, next(0) 이벤트를 3번 방출하고 ,completed를 전달하게 된다.

deferred

이번에 어떠한 step이 있는 시퀀스를 만드는 경우가 아닌, 조건에 따라 Observable을 생성하고 싶을 때 쓸 수 있는 deferred에 대해 정리해보겠다.

deferredgenerate 처럼 파라미터로 조건을 받지는 않는다.
하지만 deferred의 생성시점을 고려하면 조건과 함께 사용하는게 더 적절하다고 생각하여, 플로우 차트에 표현하였다.

정의

deferred의 정의를 보면 다음과 같다.

deferred

다른 operator와의 차이점은 구독하기 전까지 생성하지 않는다.
따라서 필요할 때 구독을 사용해 원하는 시퀀스로 생성할 수 있다.
즉 새로운 관찰자가 구독을 할때, 지정된 시퀀스를 리턴하게 된다.

코드

let factory : Observable<Int> = Observable.deferred {
    flag.toggle()
    cnt += 1
    if flag {
        return Observable.from([1,3,5])
    } else {
        return Observable.from([2,4,6])
    }
}

factory.subscribe { print("deferred toggle \(cnt) : \($0)") }
.disposed(by: disposeBag)

factory.subscribe { print("deferred toggle \(cnt) : \($0)") }
.disposed(by: disposeBag)

flag 값은 bool 타입으로 초기값은 false 로 지정해 두었다.
toggle 이 된다면, true가 되고, Observable.from([1,3,5]) 가 실행이 될 것이다.
이때, deferred의 특징상 toggle이 되기 위해서는 새로운 구독자를 추가해야한다.
만약 또다른 새로운 구독자를 추가한다면 다시 toggle이 되어, Observable.from([2,4,6]) 가 return 이 된다.

output 에서 확인 가능하다.

deferred toggle 1 : next(1)
deferred toggle 1 : next(3)
deferred toggle 1 : next(5)
deferred toggle 1 : completed
deferred toggle 2 : next(2)
deferred toggle 2 : next(4)
deferred toggle 2 : next(6)
deferred toggle 2 : completed

이 처럼 , flag를 통해 조건을 추가하여 생성을 다르게 해 줄 수 있다.


전체코드는 깃허브에서 확인 가능하다.

다음에는 filter Operator에 대해 정리해보겠다.

profile
iS를 공부하는 miori 입니다.

0개의 댓글

관련 채용 정보