1. 程式人生 > Android開發 >RxSwift 再來水一波, 某場景下,Sample 至於 withLatestFrom

RxSwift 再來水一波, 某場景下,Sample 至於 withLatestFrom

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")
        
複製程式碼