RxSwift 再來水一波, 某場景下,Sample 至於 withLatestFrom
阿新 • • 發佈:2020-06-24
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")
複製程式碼