RxSwift中的take

對於我們使用RxSwift創建的信號,如果想有條件地執行訂閱onnext,那麼我們可以對創建的信號(Observable)先調用一次take方法,下面我們來了解一下相關的take方法。

一、take相關的方法介紹
1. take(_ count: Int) -> RxSwift.Observable
// 這裏建立的信號可觀察的序列, 被訂閱時,會遍歷序列中的元素逐個發送onNext;也可以自己創建別的信號來測試
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
    .take(2) // 這裏使用了take,控制只能發送多少次
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)

這個方法是用來控制會發送多少次onNext,發送完後自動發送一個onComplete結束訂閱,如上面代碼只發送兩次,執行的結果是:
🐱
🐰

2. take<Source>(until other: Source) -> RxSwift.Observable<Self.Element>

會對第二個信號(即參數other)進行監控,當other發送了onNext或者onError,則解除訂閱(other發送onComplete則不會)。一般用於在控制器中訂閱,使訂閱關係跟隨控制器的dealloc自動取消==》 take(until: self.rx.deallocated)

let observable1 = PublishSubject<Int>()
let observable2 = PublishSubject<Void>()
observable1
    .take(until: observable2)
    .subscribe(onNext: { print($0) }, onError: { error in  print("onError")   }, onCompleted: {  print("onCompleted---")  }, onDisposed: {  print("onDisposed---")    })
    .disposed(by: disposeBag)

observable1.onNext(1)
observable2.onNext(())
// observable2.onCompleted()
// observable2.onError(RxError.take)
observable1.onNext(4)
3. take(for duration: RxTimeInterval, scheduler: SchedulerType)

duration時間內訂閱有效,過時會自動completed並且dispose。

let observable1 = PublishSubject<Int>()
observable1
    .take(for: .seconds(2), scheduler: MainScheduler.instance)
    .subscribe(onNext: { print($0) }, onError: { error in  print("onError")   }, onCompleted: {  print("onCompleted---")  }, onDisposed: {  print("onDisposed---")    })
    .disposed(by: disposeBag)

observable1.onNext(1)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {// 此時發送已經沒用了
    observable1.onNext(3)
}
4. takeLast(_ count: Int) -> RxSwift.Observable

在一個數組元素中取出最後count個元素, 如下,最後打印出"🐸", "🐷", "🐵"

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
    .takeLast(3)
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
5. take(until predicate: @escaping (Self.Element) throws -> Bool, behavior: RxSwift.TakeBehavior = .exclusive) -> RxSwift.Observable

這個方法的效果跟上述的takeUtil是一樣的,只不過判定的方式換成了使用閉包。

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
    .take(until: { str in
        print("until",str)
        return  str == "🐶" // 遇到"🐶"之後就不再接收onNext
    })
    .subscribe(onNext: {
        print("onNext",$0)
    })
    .disposed(by: disposeBag)

打印:
until 🐱
onNext 🐱
until 🐰
onNext 🐰
until 🐶

6. take(while predicate: @escaping (Self.Element) throws -> Bool, behavior: RxSwift.TakeBehavior = .exclusive) -> RxSwift.Observable

這個方法內部是調用的上述5中的方法來實現的,這裏的效果是while中返回爲false則不再接收;爲true則繼續接收。

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

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
    .take(while: { str in
        print("while", str)
        return str == "🐰"// 當條件返回true則接收信號,返回false則不再接收信號
    })
    .subscribe(onNext: {
        print("onNext",$0)
    })
    .disposed(by: disposeBag)

打印:
while 🐰
onNext 🐰
while 🐰
onNext 🐰
while 🐶

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章