ViewModel 的核心功能是把 Model 数据转换为用于 UI 呈现所需的数据。其实RxSwift 的操作符就是负责转换的,使用合适的操作符能帮我们减少代码量并提高生产力。
一、过滤操作符
001 filter 操作符用于过滤不需要的事件
func filterFunc() {
Observable.of(2,23,5,45,1,21).filter{
$0 > 20
}.subscribe(onNext:{
print($0);
}).disposed(by:disposeBag)
}
打印: 23 45 21
002 distinctUntilChanged用于把相同的事件过滤掉。还可以过滤相同状态,从而避免频繁更新UI
Observable.of(1, 1, 2, 2, 3,2,2,4,4).distinctUntilChanged().subscribe(onNext:{
print($0);
}).disposed(by:disposeBag)
打印:1 2 3 2 4
二、转换操作符
转换操作符可以将一种数据类型转换成另外一种类型
001 map
func mapFunc() {
Observable.of(1, 2, 3,4).map{"String:" + String($0)}.subscribe(onNext:{
print($0);
}).disposed(by:disposeBag)
}
002 compactMap 过滤掉值为nil的操作符 结合了filter和map功能的操作符 filter 把nil
的值过滤掉,而 map 把非空的值进行转换。
003 flapMap 把两层的observable序列合并到一起
func temperatureFunc() {
struct TemperatureSensor {
let temperature: Observable<Int>
}
let sensor1 = TemperatureSensor(temperature: Observable.of(21, 22,23))
let sensor2 = TemperatureSensor(temperature: Observable.of(22, 25))
Observable.of(sensor1, sensor2)
.flatMap { $0.temperature }
.distinctUntilChanged()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
}
打印:21 22 23 25
三、合并操作
001 startWith 可以使订阅者在收到序列事件之前,先收到传给startWith的事件。
func startWithFunc() {
Observable.of(1, 2)
.startWith(3, 4)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
}
打印: 3 4 1 2
在项目中加载事件插入网络事件之前,以此来保持UI状态的自动更新
002 contact 能够将多个OB序列按顺序合并在一起
Observable.of(1, 2)
.concat(Observable.of(3, 4))
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
打印 1、2、3、4
在项目中例如可以将下一页的数据加到前一页数据的后面
003 merge 用于合并多个OB序列的操作符,他能保持原来事件的顺序
let first = PublishSubject<Int>()
let second = PublishSubject<Int>()
Observable.of(first, second)
.merge()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
first.onNext(1)
first.onNext(2)
second.onNext(11)
first.onNext(3)
second.onNext(12)
second.onNext(13)
first.onNext(4)
next
事件时,就会从另外一个 PublishSubject 取出其最后一个事件,然后调用
combineLatest
方法的闭包,把这两个事件合并起来并通知订阅者。上述的例子在执行时会打印 1a、2a、2b、2c、3c、4c 5c。
let first = PublishSubject<String>()
let second = PublishSubject<String>()
Observable.combineLatest(first, second) { $0 + $1 }
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
first.onNext("1")
second.onNext("a")
first.onNext("2")
second.onNext("b")
second.onNext("c")
first.onNext("3")
first.onNext("4")
first.onNext("5")
我们可以用它来监听多个 Observable 序列,然后组合起来统一更新状态。例如在一个登录页面里面,我们可以同时监听用户名和密码两个输入框,当它们同时有值的时候才激活登录按钮。
005 zip也能用于合并两个 Observable 序列,和 combineLatest 不一样的地方是, zip 只会把两个 Observable 序列的事件配对合并。就像两队小朋友,排在前头的手牵手来到一个新队列。一旦出来就不再留在原有队列了。
打印 1a 2b 3c 4d
let first = PublishSubject<String>()
let second = PublishSubject<String>()
Observable.zip(first, second) { $0 + $1 }
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
first.onNext("1")
second.onNext("a")
first.onNext("2")
second.onNext("b")
second.onNext("c")
first.onNext("3")
first.onNext("4")
second.onNext("d")
first.onNext("5")