RxSwift

4. RxSwift Operator(2)

Daesiker 2021. 9. 30. 10:34
반응형

1. Combining Operators

StartWith

이벤트를 방출하기 전 startWith의 파라미터 값 이벤트를 첫번째로 방출한다.

2개 이상 사용가능하며 마지막으로 사용한 startWith의 파라미터부터 방출한다.

let bag = DisposeBag()
let numbers = [1, 2, 3, 4, 5]

Observable.from(numbers)
    .startWith(-1, 0)
    .startWith(-2)
    .subscribe {
        print($0)
    }
    .disposed(by: bag)

// -2
// -1
// 0
// 1
// 2
// 3
// 4
// 5

예제를 보면 가장 마지막에 호출한 startWith의 파라미터인 -2부터 방출된걸 알 수 있다.

Concat

concat은 2개 이상의 Observable을 이어서 1개의 Observable을 만들어준다.

첫번째 옵저버블이 complete 가 호출되면 그다음 옵저버블이 이벤트를 방출하기 시작한다.

첫뻔째 모든 요소가 방출 되어야 다음 옵저버블 방출한다.

let bag = DisposeBag()
let fruits = Observable.from(["apple", "kiwi", "peach", "lemon", "watermelon"])
let animals = Observable.from(["dog", "cat", "monkey", "panda", "lion"])


//Observable.concat(fruits, animals)
//    .subscribe {
//        print($0)
//    }
//    .disposed(by: bag)


fruits.concat(animals)
    .subscribe {
        print($0)
    }
    .disposed(by: bag)

//apple
//kiwi
//peach
//lemon
//watermelon
//dog
//cat
//monkey
//panda
//lion

fruits 배열에 있는 모든 원소가 방출되고 complete가 호출되자 animals의 원소가 방출된걸 알 수 있다.

Observable에서 concat을 사용해서 합칠 수도 있고 하나의 Observable 객체에서 concat을 호출하여 합칠 수도 있다.

combineLatest

combineLatest Operator는 2개 이상의 Observable을 합치되 각각의 Observable의 원소가 여러개일 경우 가장 마지막에 들어온 원소를 합친 뒤 방출한다.

let bag = DisposeBag()

enum MyError: Error {
   case error
}

let greetings = PublishSubject<String>()
let languages = PublishSubject<String>()


Observable.combineLatest(greetings, languages) { (greet, language) -> String in
    greet + " " + language
}
.subscribe {
    print($0)
}
.disposed(by: bag)

greetings.onNext("hi")
languages.onNext("World")
// hi World
greetings.onNext("Hello")
//Hello World

languages.onNext("RxSwift")
//Hello RxSwift

languages.onNext("SwiftUI")
//Hello SwiftUI

맨 처음 String 타입의 PublishSubject 2개를 선언한다.

PublishSubject는 나중에 자세히 설명할 예정이고 지금은 값이 nil인 Observable이라고 생각하면 된다.

combineLatest Operator을 통해 2개의 Observable을 하나의 String으로 합친 뒤 subscribe 이벤트를 통해 방출하는 것을 볼 수 있다.

그 다음에 greetings Observable의 onNext 를 사용하여 "hi"라는 원소를 넣어주는데 이 때는 languages Observable의 값이 없기 때문에 아무일도 일어나지 않는다.

languages Observable에 "World" 원소를 넣자 combineLatest Operator을 통해 "hi World"가 출력되는 이벤트가 방출된 것을 알 수 있다. greetings에 또 다른 원소 "Hello"를 넣으면 CombineLatest는 이전에 원소를 가장 최신의 원소인 "Hello"로 바꾼 뒤 "Hello World"를 출력하는 것을 알 수 있다.


2. Conditional Operators

amb

amb Operator은 2개 이상의 Observable에서 원하는 Observable의 이벤트만 방출해 준다.

let bag = DisposeBag()

enum MyError: Error {
   case error
}

let a = PublishSubject<String>()
let b = PublishSubject<String>()
let c = PublishSubject<String>()


//a.amb(b)
Observable.amb([a, b, c])
    .subscribe {
        print($0)
    }
    .disposed(by: bag)


a.onNext("a")
//a
b.onNext("b")
a.onNext("a")
//a
a.onNext("aa")
//aa
b.onNext("bb")


a.onCompleted()

앞선 예제와 마찬가지로 a,b,c라는 String타입의 PublichSubject를 선언해주고 amb를 통해서 3개의 Observable을 하나로 묶은 뒤 각각의 Observable의 원소를 넣어주었다. amb에서 가장 앞에 있는 Observable인 a에 원소를 넣어줄 때면 이벤트를 방출하지만 나머지 Observable인 b와 c에 원소를 넣어주면 아무 이벤트가 방출되지 않은 것을 알 수 있다.

솔직히 어디에다가 써야할지 모르겠다...


Time-based Operators

interval

interval은 원하는 시간단위와 스케줄러를 선택한뒤 해당 시간마다 원하는 스케줄러에 이벤트를 방출할 수 있게 도와주는 Operator이다.

let bag = DisposeBag()

let o1 = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe {
        print($0)
    }

DispatchQueue.main
    .asyncAfter(deadline: .now() + 5) {
        o1.dispose()
    }

//0
//1
//2
//3
//4

o1은 interval Operator을 통해 1초마다 이벤트를 메인 스케줄러에서 방출하는 Observable이다. 시작은 0부터 시작하며 0부터 이벤트를 방출하는 것을 알 수 있다.

이제 DispatchQueue를 이용하여 main 스케줄러에 접근한 뒤 asyncAfter을 이용하여 현재시간에서 5초뒤에 dispose()라는 메서드를 사용하는데 dispose는 interval 이벤트를 그만 방출하고 싶을 때 호출하는 메서드이다.

출력 결과를 보면 0 ~ 4초까지 이벤트가 발생하고 5초부터 이벤트가 방출되지 않은 것을 알 수 있다.

반응형

'RxSwift' 카테고리의 다른 글

6. RxSwift Relay, Signal, Driver  (0) 2021.10.07
5. RxSwift Subject  (0) 2021.10.03
3. RxSwift Oporator(1)  (0) 2021.09.07
2. RxSwift Observable이란?  (0) 2021.09.02
1. RxSwift란?  (0) 2021.08.23