먹고 기도하고 코딩하라

[RxSwift] (2) Observable 생성 오퍼레이터와 subscribe 본문

앱/Swift

[RxSwift] (2) Observable 생성 오퍼레이터와 subscribe

사과먹는사람 2022. 11. 16. 11:21
728x90
728x90

 

Observable을 생성할 수 있는 오퍼레이터들은 다음과 같은 것들이 있다.

subscribe는 문서 하단에서 설명하겠다.

 

 

Observable 생성 오퍼레이터

 

 

  • just(_ element: T) -> Observable<T>
    • 1개의 요소만 갖고 방출하는 Observable 시퀀스를 만들어 반환한다.
    • 엄밀히 말하면 1개의 아이템을 그 아이템을 방출하는 Observable로 변환하는 오퍼레이터다. From과 비슷하지만, From은 배열이나 순회 가능한 요소들을 받아서 순회해서 방출하지만, just의 경우 배열을 받아도 배열 자체를 방출한다. 
    • just에 1개 이상의 요소를 매개변수로 줄 수 없다. 이 경우 컴파일 에러가 난다.
Observable<Int>
    .just(1)
    .subscribe(onNext: {
        print($0)	// 1
    })
Observable
    .just([1, 2, 3])
    .subscribe(onNext: { print($0 )} )	// [1, 2, 3]

 

  • of(_ elements: T..., scheduler: ImmediateSchedulerType) -> Observable<T>
    • 1개 이상의 요소를 갖고 방출할 수 있는 Observable 인스턴스를 만들어 반환한다.
    • 주의할 점은 배열 자체를 of에 넣으면 배열 안의 요소를 하나씩 방출하는 게 아니라 배열 자체를 방출한다는 점이다. (이 점에선 just와 동일하다)
Observable<Int>
    .of(1, 2, 3, 4, 5)
    .subscribe(onNext: {
        print($0)	// 1 2 3 4 5
    })
Observable
    .of([1, 2, 3, 4, 5])
    .subscribe(onNext: {
        print($0)	// [1, 2, 3, 4, 5]
    })

 

 

  • from(_ array: [T], scheduler: ImmediateSchedulerType) -> Observable<T>
    • 배열을 Observable 시퀀스로 변환한다. 배열 안의 요소를 순회해 1개씩 방출한다.
    • ReactiveX.io에서는 다른 객체나 자료 구조를 Observable로 변환하는 오퍼레이터라고 소개하고 있다.
Observable<Int>
    .from([1, 2, 3, 4, 5])
    .subscribe(onNext: {
        print($0)	// 1 2 3 4 5
    })

 

  • empty() -> Observable<()>
    • 빈 Observable 시퀀스를 반환한다. completed 메시지를 보내거나 즉시 종료하는 Observable을 만들고 싶을 때 사용할 수 있다.
    • 어떤 아이템도 방출하지 않지만, 정상적으로 종료되는 Observable을 생성한다.
Observable<Void>
    .empty()
    .subscribe {
        print($0)	// completed
    }

 

 

  • never() -> Observable<Any>
    • 절대 종료되지 않는(=complete되지 않는) Observable 시퀀스를 반환한다. 무한정 지속됨을 나타내는 데 사용된다고 한다.
    • 어떤 아이템도 방출하지 않고, 종료도 되지 않는다.
    • 이런 Observable은 debug() 메소드로 동작을 확인할 수 있다.
Observable.never()
    .subscribe(
        onNext: {
            print($0)
        },
        onCompleted: {
            print("Completed")
        }
    )
// 아무 응답이 없음

 

 

  • range(start: Int, count: Int, scheduler: ImmediateSchedulerType) -> Observable<Int>
    • 특정한 스케줄러를 이용해 Observer 메시지를 생성하고 보내는, 특정 range의 정수들을 담는 Observable 시퀀스를 생성한다. 
    • 이 range는 연속된 범위이다.
Observable.range(start: 1, count: 9)
    .subscribe(onNext: {
        print("2 * \($0) = \(2 * $0)")	// 구구단 2단
    })

 

 

  • create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element>
    • Observable 시퀀스를 생성하는 메소드이다. 다른 생성 오퍼레이터들과 달리 특이한 점이라면, Observer를 매개변수로 받는 클로저를 매개변수로 전달받는다는 점이다. Observer의 onNext, onError, onCompleted 메소드를 적절히 호출한다. 마치 Observable처럼 동작하도록 작성하는 것이다! 말도 안돼..
    • 반드시 onCompleted나 onError를 딱 1번 호출해야 하며, 그 뒤로는 다른 어떤 메소드도 호출하지 말아야 한다. 
    • 직접 코드 구현을 통해서 Observer 메소드를 호출해서 Observable을 생성한다.
Observable.create { observer -> Disposable in
    observer.onNext(1)
    observer.on(.next(2))   // 위 문장과 똑같음
    observer.onNext(3)
    observer.onCompleted()
    return Disposables.create()
}
.subscribe {
    print($0)   // next(1) next(2) next(3) completed
}

 

 

  • deferred(_ observableFactory: @escaping () throws -> Observable<Element>) -> Observable<Element>
    • Observer 구독이 붙을 때마다 특정 factory 함수를 호출하는 Observable 시퀀스를 반환한다.
    • 좀 이해하기 어려운데, 간단히 설명하자면 Observer 구독 전에는 Observable 생성이 되지 않는다. Observer가 구독하기 시작하면, Observer별로 새로운 Observable을 생성하는 오퍼레이터다.
    • 각 Observer들끼리는 같은 Observable을 구독하고 있다고 생각하겠지만 사실 각 Observer는 각각의 개별 시퀀스를 구독하고 있는 것이다.
var flip: Bool = false
let factory: Observable<String> = Observable.deferred {
    flip = !flip
    
    if flip {
        return Observable.of("🍿")
    } else {
        return Observable.of("🍰")
    }
}
for _ in 0...3 {
    factory.subscribe(onNext: {
        print($0)	// 🍿 🍰 🍿 🍰
    })
    .disposed(by: disposeBag)
}

 

Subscribe

위에서 계속 Observable 인스턴스에 .subscribe를 붙였다. subscribe는 Observable과 Observer를 연결해서 Observable의 아이템 방출과 알림을 구독하는 오퍼레이터다. Observable 시퀀스에 대해 엘리먼트 핸들러, 에러 핸들러, 컴플리션 헨들러, 디스포즈 핸들러를 붙인다.

func subscribe(
    onNext: ((Element) -> Void)? = nil,
    onError: ((Swift.Error) -> Void)? = nil,
    onCompleted: (() -> Void)? = nil,
    onDisposed: (() -> Void)? = nil
) -> Disposable
  • onNext : Observable 시퀀스는 요소를 방출할 때마다 이 메소드를 호출한다. Observable에서 방출된 아이템이 매개변수이다.
  • onError : Observable 시퀀스는 에러가 발생했을 때 이 메소드를 호출한다. Observable은 종료되고, onNext, onCompleted 등을 더 이상 호출할 수 없다. 에러가 일어난 원인인 Error가 매개변수이다.
  • onCompleted : Observable 시퀀스는 성공적으로 종료될 때 이 메소드를 호출한다. 에러 없이 마지막 onNext를 호출하는데 성공한 다음 호출한다.  
  • onDisposed : 시퀀스가 어떤 방식으로든 종료되었을 때 호출한다. (completed, error, 구독 취소로 생성이 취소될 때 등)

 

 

728x90
반응형
Comments