對於我們使用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 🐶