본문 바로가기

Swift/RxSwift

[🌱SeSAC] Creating and Subscribing to Observables

728x90

Rx.playground 파일에서 Creating and Subscribing to Observables 을 실행해보자.

 

Creating and Subscribing to Observables

There are several ways to create and subscribe to Observable sequences.

 

Operatings > Creators > Empty/Never

#empty

Creates an empty Observable sequence that only emits a Completed event.

 

empty는 아무 것도 emit하지 않는 옵저버블을 생성하지만 정상적으로 종료시킨다.
즉, 빈 값으로 종료 시키는 것이다.

 

✅ 즉시 종료 되는 옵저버블을 만들고 싶거나,

✅ 빈 값을 반환하고 싶을 때 사용한다.

 

example("empty") {
    let disposeBag = DisposeBag()
    
    Observable<Int>.empty()
        .subscribe { event in
            print(event)
        }
        .disposed(by: disposeBag)
}

위의 코드를 실행하면 

시작하고 끝이 나는데, 그 과정에서 아무것도 반환하지 않는다.

 

 

#never

Creates a sequence that never terminates and never emits any events.

 

never은 아무것도 emit하지 않고 종료되지도 않는다. 
즉, 무한한 상태를 의미한다.

 

example("never") {
    let disposeBag = DisposeBag()
    let neverSequence = Observable<String>.never()

    let neverSequenceSubscription = neverSequence
        .subscribe { _ in
            print("This will never be printed")
    }

    neverSequenceSubscription.disposed(by: disposeBag)
}

위의 코드를 실행하면 

이렇게 아무것도 반환하지 않고 끝나지 않는 것을 볼 수 있다.

 

 

Operatings > Creators > Just

#just

Creates an Observable sequence with a single element. 

 

Just는 바로 그 아이템을 방출하는 Observable로 변환한다.

Just는 From과 비슷하지만 From은 배열이나 반복 가능한 항목 또는 그와 같은 종류의 항목으로 하나씩 내보낼 항목을 꺼내는 반면 Just는 배열이나 반복 가능한 항목 또는 가진 것을 그대로 단일 항목으로 내보낸다. 

(예를 들어서 ["a", "b", "c"]라는 배열 항목이 있을 때, Just의 경우 ["a", "b", "c"] 이렇게 하나로 반환하는 한편, From은 "a" 방출되고, "b"방출되고, "c"가 방출된다.)

 

example("just") {
    let disposeBag = DisposeBag()
    
    Observable.just("🔴")
        .subscribe { event in
            print(event)
        }
        .disposed(by: disposeBag)
}

위의 코드를 실행하면 

아래처럼 실행되고 아이템을 하나로 방출한 다음 끝이 나는 것을 볼 수 있다.

 

Just VS From 

example("just") {
    let disposeBag = DisposeBag()

    Observable.just(["🐶", "🐱", "🐭", "🐹"])
        .subscribe { event in
            print(event)
        }
        .disposed(by: disposeBag)
}

example("from") {
    let disposeBag = DisposeBag()
    
    Observable.from(["🐶", "🐱", "🐭", "🐹"])
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}

같은 아이템에 대해서 just는 하나의 아이템으로 반환하지만, from은 각 배열의 요소를 반환한다. 

 

코드를 실행하면 위와 같이 출력되는 것을 볼 수 있다.

 

 

#of

Creates an Observable sequence with a fixed number of elements.

 

example("of") {
    let disposeBag = DisposeBag()

    Observable.of("🐶", "🐱", "🐭", "🐹")
        .subscribe(onNext: { element in
            print(element)
        })
        .disposed(by: disposeBag)
}

 

subscribe(onNext:)가 무엇인지 -> [더보기]를 통해 확인할 수 있다. 

 

더보기

여기서 새롭게 적용된 함수는 subscribe(onNext:)이다.

 

이 예에서는 subscribe(onNext:) 방법도 소개한다.

모든 이벤트 유형(다음, 오류 및 완료)에 대해 이벤트 처리기를 구독하는 subscribe(_:)와 달리 subscribe(onNext:)는 오류 및 완료 이벤트를 무시하고 다음 이벤트 요소만 생성하는 요소 처리기를 구독한다.

이벤트 유형만 구독하려면 구독(error:) 및 구독(onCompleted:) 방법도 있습니다. 또한 구독(onNext:onError:onCompleted:onDisposed:) 메서드가 있습니다. 이 메서드를 사용하면 하나 이상의 이벤트 유형에 대응하고 구독이 어떤 이유로든 종료되거나 삭제될 때 단일 호출에서 응답할 수 있다.

 

위의 코드를 실행하면 

 

이렇게 요소들이 출력 되는 것을 볼 수 있다. 

 

just와 of의 차이는 여러 아이템을 보낼 수 있는가 없는가의 차이이다.

just에서 배열 하나의 요소가 아닌 각 문자 여러개를 보내려고 하면 위와 같이 오류가 나타나는 것을 볼 수 있다.

반면에 of의 경우 여러 요소를 한번에 보낼 수 있다.

 

 

#from

Creates an Observable sequence from a Sequence, such as an Array, Dictionary, or Set

 

example("from") {
    let disposeBag = DisposeBag()
    
    Observable.from(["🐶", "🐱", "🐭", "🐹"])
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
또한 위의 예에서는 인수 이름을 명시적으로 지정하는 대신 기본 인수 이름 $0을 사용하는 방법을 보여준다. 

 

위의 코드를 실행하면 

 

이렇게 출력되는 것을 확인할 수 있다.

 

위의 just와의 비교에서도 알 수 있는 것처럼 from의 경우, Sequence로부터의 요소에 대한 시퀀스 이벤트 알림을 전달하고 싶을 때 사용한다. 즉, 배열, 집합 등에서 하나의 요소씩 이벤트를 처리하고 싶을 때 해당 메서드를 사용한다.

 

 

#create

Creates a custom Observable sequence.

 

설명에서 알 수 있는 것처럼 커스텀 옵저버블 시퀀스를 만들 수 있다.

이 연산자는 직접 Observable 시퀀스를 구성할 때 사용한다.

 

 

 

example("create") {
    let disposeBag = DisposeBag()
    
    let myJust = { (element: String) -> Observable<String> in
        return Observable.create { observer in
            observer.on(.next(element))
            observer.on(.completed)
            return Disposables.create()
        }
    }
        
    myJust("🔴")
        .subscribe { print($0) }
        .disposed(by: disposeBag)
}

위의 코드를 실행하면 

 

이렇게 출력되는 것을 볼 수 있다. 

 

 

#range

시작과 끝을 지정하고 그 안의 연속적인 숫자에 대한 이벤트를 처리하고 싶을 때 사용할 수 있다.

 

example("range") {
    let disposeBag = DisposeBag()

    Observable.range(start: 1, count: 10)
        .subscribe { print($0) }
        .disposed(by: disposeBag)
}

위의 코드를 실행하면 

 

1부터 10까지 그 안의 연속적인 이벤트가 발생한 것을 볼 수 있다.

 

 

#repeatElement

이름에서 어느정도 유추할 수 있는 것처럼 어떤 이벤트(= 요소)를 반복할 때 사용한다.

 

example("repeatElement") {
    let disposeBag = DisposeBag()
    
    Observable.repeatElement("🔴")
        .take(3)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}

위의 코드를 실행하면 

 

요소인 🔴가 3번 반복되어서 출력된 것을 확인할 수 있다.

 

take()의 경우, 서버통신을 할 때 사용할 수도 있는데, 
예를 들어 어떤 API에서 데이터를 받아와야 할 때 한번 시도하는 것이 아니라 5번 정도 시도하도록 제한을 줄 수 있다.
(서버 통신이 바로 되지 않더라도 시도할 수 있도록) 

 

 

#generate 

Creates an Observable sequence that generates values for as long as the provided condition evaluates to true.

 

요소를 생성하는데, 클로저 구문 안의 조건을 만족하는 요소만 생성하는, 그 요소에 대해서만 이벤트를 방출하는 메서드이다. 

 

example("generate") {
    let disposeBag = DisposeBag()
    
    Observable.generate(
            initialState: 0,
            condition: { $0 < 3 },
            iterate: { $0 + 1 }
        )
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}

위의 코드를 보게 되면, 

  • 초기 시작은 0에서 시작하고
  • 3보다 작은 값에 대해서 
  • 1씩 더하도록 이벤트를 방출하고 
  • 이를 출력하고 있다.

 

그러므로 이를 실행하면 아래와 같이 나오는 것을 확인할 수 있다.

0부터 시작해서 1씩 더하고 출력하는데, 이를 3보다 작을 때까지 이벤트를 emit하는 것이다.

그러므로 0, 1, 2의 값이 출력된다. 

 

 

'Swift > RxSwift' 카테고리의 다른 글

[🔥Rx뿌셔] Subscribe  (0) 2022.10.25
[🔥Rx뿌셔] Observable  (2) 2022.10.24
[🔥Rx뿌셔] Intro  (1) 2022.10.24
[🌱SeSAC] Rx.playground 실행하는 방법  (1) 2022.10.24
[🌱SeSAC] 마침내 피할 수 없는 아 .. 알엑스  (0) 2022.10.24