Sample 至于 withLatestFrom,
场景是,控制器界面的一个按钮请求数据,另一个按钮调用最新的数据
( 因为按钮的点击时机不确定,就比较异步,很 Rx 响应式 )
这里区分出了主要的事件,辅助的事件 ( 来控制的 )
一个按钮请求数据,输入事件流,是事件仓库
另一个按钮调用最新的数据,控制事件流,决定前一个事件流的处理时机 ( 前一个事件流,只处理需要的,无用的事件抛弃 )
let firstSubject = PublishSubject<String>()
let secondSubject = PublishSubject<String>()
firstSubject.sample(secondSubject).subscribe(onNext: { (memo) in
print(memo)
}).disposed(by: rx.disposeBag)
firstSubject.onNext("1")
secondSubject.onNext("A")
firstSubject.onNext("2")
secondSubject.onNext("B")
secondSubject.onNext("C")
firstSubject.onNext("3")
firstSubject.onNext("4")
secondSubject.onNext("D")
firstSubject.onNext("5")
打印:
1 2 4
sample 升级一下,
一个事件流,是事件仓库
另外一个事件流,决定前一个事件流的处理时机 ( 前一个事件流,只处理需要的,无用的事件抛弃 )
处理前一个事件流的时候,也要用到第二个事件流的数据
这个时候,一般情况下可以用 withLatestFrom
let firstSubject = PublishSubject<String>()
let secondSubject = PublishSubject<String>()
firstSubject.withLatestFrom(secondSubject){
(first, second) in
return first + second
}
.subscribe(onNext: { print($0) })
.disposed(by: rx.disposeBag)
firstSubject.onNext("1")
secondSubject.onNext("A")
firstSubject.onNext("2")
secondSubject.onNext("B")
secondSubject.onNext("C")
secondSubject.onNext("D")
firstSubject.onNext("3")
firstSubject.onNext("4")
firstSubject.onNext("5")
打印:
2A 3D 4D 5D
结一下:
-
用 sample ,输入事件流,然后控制事件流
-
用 withLatestFrom ,控制事件流,然后输入事件流
withLatestFrom , 可能会出现反复的采样sample ,
譬如例子结尾打印的
3D 4D 5D
- 而 sample 则只采样一次,
第一个例子的
2
只打印一次
另一种拓展 Sample 的方式:
let firstSubject = PublishSubject<String>()
let secondSubject = PublishSubject<String>()
Observable.zip(secondSubject.sample(firstSubject), firstSubject){
(first, second) in
return first + second
}
.subscribe(onNext: { print($0) })
.disposed(by: rx.disposeBag)
secondSubject.onNext("A")
firstSubject.onNext("2")
secondSubject.onNext("B")
secondSubject.onNext("C")
secondSubject.onNext("D")
firstSubject.onNext("3")
firstSubject.onNext("4")
firstSubject.onNext("5")
打印:
A2 D3
这样标准了一些, 不会反复 sample ,
但需保证输入事件流 secondSubject 先走,再走控制事件流 firstSubject
secondSubject 之间,只能有一个 firstSubject,
还需保证 ...
(基于 zip 的特性 )
这样就不行了
firstSubject.onNext("1") // 这里
secondSubject.onNext("A")
firstSubject.onNext("2")
secondSubject.onNext("B")
secondSubject.onNext("C")
secondSubject.onNext("D")
firstSubject.onNext("3")
firstSubject.onNext("4")
firstSubject.onNext("5")
这也不行
firstSubject.onNext("1")
secondSubject.onNext("A")
firstSubject.onNext("2")
secondSubject.onNext("B")
secondSubject.onNext("C")
firstSubject.onNext("3") // 这里
firstSubject.onNext("4") // 这里
secondSubject.onNext("D")
firstSubject.onNext("5")