Overview
RxSwift 提供了多种操作符(Operator),如果你了解 Swift 的高阶函数,比如 map(_:)
等,那么你也应该很容易就能明白操作符做了什么事情。
RxSwift 的操作符主要有以下几种类型:
- Filtering Operators
- Transforming Operators
- Combining Operators
- Time-Based Operators
Filtering Operators
Ignoring operators
[图片上传失败...(image-fe720e-1639236680002)]
ignoreElements
: 忽略所有 next 事件,只允许终止事件,比如 completed 和 error 事件。其实 ignoreElements 返回的就是一个 Completable。
[图片上传失败...(image-1891a3-1639236680002)]
elementAt(_:)
: 只允许第 n 个元素通过。一旦第 n 个元素通过之后,订阅就会被终止。
[图片上传失败...(image-cda43e-1639236680002)]
filter
: 只允许符合条件的元素通过,比如 filter { $0 < 3 }
只允许通过小于 3 的元素。
Skipping operators
[图片上传失败...(image-2c4f4d-1639236680002)]
skip
: 跳过前 n 个元素,只允许后面的元素通过。
[图片上传失败...(image-b38da3-1639236680002)]
skipWhile
: 跳过符合条件的元素。当第一个允许跳过的元素被发出时,后面的所有元素都允许通过,包括符合条件的元素。
let disposeBag = DisposeBag()
// 1
Observable.of(2, 2, 3, 4, 4)
// 2
.skipWhile { $0.isMultiple(of: 2) }
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
/**
第一个允许通过的元素 3 通过后,后面的所有元素都允许跳过,即使后面的 4 也符合条件
output: 3, 4, 4
**/
[图片上传失败...(image-3389d8-1639236680002)]
skipUntil
: 前面的操作符都是根据静态条件进行过滤,如果像动态地过滤元素,可以使用 skipUntil
操作符。skipUntil
会持续过滤元素,直到你订阅另一个 observable 并触发它发出元素,然后后面的所有元素都可以通过。
let disposeBag = DisposeBag()
// 1
let subject = PublishSubject()
let trigger = PublishSubject()
// 2
subject
.skipUntil(trigger)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
// 这里 trigger 发出了元素,因此后面的 C 将不再被过滤
trigger.onNext("X")
subject.onNext("C")
// --- Example of: skipUntil ---
// C
Taking operators
Taking 正好和 Skipping 相反。
[图片上传失败...(image-42ce0e-1639236680002)]
take
: 只允许前 n 个元素通过。
[图片上传失败...(image-19786a-1639236680002)]
takeWhile
: 只允许符合条件的元素通过。
[图片上传失败...(image-43607d-1639236680002)]
takeUntil
: 只发出符合条件之前的元素,.inclusive
可以允许通过第一个符合条件的元素。.exclusive
则不可以。比如图示中的,第一个符合条件的元素是 2,如果 使用 .inclusive
, 则允许通过的元素为 1, 2,如果使用 .exclusive
, 则允许跳过的元素为 1。
[图片上传失败...(image-61a641-1639236680002)]
takeUntil
:和skipUntil
类似,可以根据动态的条件允许元素通过。比如在另一个 observable 被触发之前的元素可以被通过。
let disposeBag = DisposeBag()
// 1
let subject = PublishSubject()
let trigger = PublishSubject()
// 2
subject
.takeUntil(trigger)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// 3
subject.onNext("1")
subject.onNext("2")
// 这里 trigger 发出元素后,subject 后面发出的元素将不能通过
trigger.onNext("X")
subject.onNext("3")
/**
output: 1, 2
**/
Distinct operators
[图片上传失败...(image-9a7e3c-1639236680002)]
distinctUntilChanged
: 防止紧挨着的重复元素通过。比如 A, A, B, B, A, 只允许通过的元素为:A, B, A.
[图片上传失败...(image-3aba38-1639236680002)]
distinctUntilChanged{}
: 防止符合条件的紧挨着的元素通过。