Tunko Development Diary

RxSwift) Filtering Operators (take) 본문

Development/RxSwift

RxSwift) Filtering Operators (take)

Tunko 2022. 6. 1. 02:57

take

let disposeBag = DisposeBag()
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Observable.from(numbers)
    .take(5)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(1)
next(2)
next(3)
next(4)
next(5)
completed

take 인자로 들어간 count만큼 방출합니다.

take(while:)

let disposeBag = DisposeBag()
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Observable.from(numbers)
    .take(while: { $0 < 3} )
    .subscribe { print($0) }
    .disposed(by: disposeBag)

Observable.from(numbers)
    .take(while: { $0 < 3}, behavior: .inclusive )
    .subscribe { print($0) }
    .disposed(by: disposeBag)
// while 조건에 맞지 않더라도 마지막에 확인한 값도 호출됩니다.

Observable.from(numbers)
    .take(while: { $0 < 3}, behavior: .exclusive )
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(1)
next(2)
completed
next(1)
next(2)
next(3)
completed
next(1)
next(2)
completed

함수 원형

public func take(while predicate: @escaping (Element) throws -> Bool,
                     behavior: TakeBehavior = .exclusive)
        -> Observable<Element> {
    take(until: { try !predicate($0) }, behavior: behavior)
}

while 조건이 true 일때 인자를 방출합니다. behavior 파라미터는 기본으로 .exclusive 로 설정되어있습니다.(behavior : .inclusive) 일때는 조건에 상관없이 마지막으로 확인한 값이 방출됩니다.

take(until:)

let disposeBag = DisposeBag()

let subject1 = PublishSubject<Int>()
let subject2 = PublishSubject<Int>()

subject1.take(until: subject2)
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

subject1.onNext(1)
subject1.onNext(2)
subject2.onNext(1)
subject1.onNext(3)

출력

next(1)
next(2)
completed

파라미터로 전달된subject2에서 Next 이벤트를 전달하기 전까지 subject1 은 그대로 이벤트를 방출합니다. 하지만 subject2에서 next 이벤트를 방출하게 되면 subject1 은 completed가되면서 종료됩니다.

subject1.take(until: { $0 > 5})
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

subject1.onNext(1)
subject1.onNext(2)
subject1.onNext(3)
subject1.onNext(4)
subject1.onNext(5) // 여기서 종료!
subject1.onNext(6)
subject1.onNext(7)

출력

next(1)
next(2)
next(3)
next(4)
next(5)
completed

take(until:) 에서도 behavior: 인자가 포함될 수 있습니다. 앞서 본 take(while:)에서와 같이 동작합니다.

takeLast

let disposeBag = DisposeBag()

let subject = PublishSubject<Int>()
subject.takeLast(4)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

(1...10).forEach {
    subject.onNext($0)
}
subject.onNext(11)
subject.onCompleted()

Observable.from([1,2,3,4,5,6])
    .takeLast(3)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(8)
next(9)
next(10)
next(11)
completed
next(4)
next(5)
next(6)
completed

마지막에 전달한 인자를 takeLast 파라미터 갯수만큼만 방출합니다.

take(for:)

Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .take(for: .seconds(4), scheduler: MainScheduler.instance)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(0)
next(1)
next(2)
completed

take(for:)에 들어간 인자 시간 만큼만 인자를 방출하고 completed 합니다. 시간에 밀리세컨드 만큼 오차가 발생하는것을 유의해야 합니다.

4초의 시간동안 방출했지만 들어온 이벤트는 1초당 3개만들어왔습니다.

반응형
Comments