iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
Mobile Development

RxSwift / 30天探索之旅系列 第 16

第 16 天 - 統整一下Operator的選擇

  • 分享至 

  • xImage
  •  

嗨,今天把過去這幾天所講的Operator做個統整,並分享過去犯錯的範例,給大家借鏡借鏡。

Merge、CombineLatest和Zip

相同之處

  1. 都可以合併多個Observable

不同之處

  1. merge需要是相同型態,combineLatestzip可以是不同型態
  2. merge只要其中有一條Observable有發送元素,就成立,而combineLatestzip則需要每一條都至少發送過一個元素後才成立

使用時機

  1. merge:當需要統合多個resources
  2. combineLatest:當resources只取最新的
  3. zip:當resources需要一起出現

CombineLatest和WithLatestFrom

相同之處

  1. 都是合併最新的元素

不同之處

  1. combineLatest可合併多個Observable
  2. withLatestFrom是一個Observable為主,去取另一個Observable最新元素,共兩個

使用時機

  1. withLatestFrom:當一個事件觸發時,去結合另一個resource

自身錯誤範例
這是我翻很久之前跟學長對話的訊息發現的,剛好拿出來當作錯誤範例(笑)

情境大概像這樣,我想要點了按鈕去『取得』另一個Observable『最新』的資料,簡化後的程式大概像下面這樣

// 錯誤示範
let subject = PublishSubject<String>()

let resultObservable = Observable.combineLatest(button.rx.tap, subject)

resultObservable
    .debug("Result")
    .subscribe()
    .disposed(by: disposeBag)

現在看起來,錯,錯的離譜,錯的荒唐,不過我當初確實這樣寫,這樣寫跟預期的結果有落差

  1. 正常情況下,若subject已有元素,我點擊按鈕,確實resultObservable能做到『取得』subject『最新』的元素,元素可能像這樣((), "A")
  2. 但當subject接收到新的元素,也就是說它值不一樣了,這時resultObservable同樣也會發送最新元素((), "B")

這樣就不是我們想要的樣子了,一些情境下看起來正常,但在另一情境下就怪怪的,用錯operator就會這樣...,所以改成下面這樣

let resultObservable = button.rx.tap.withLatestFrom(subject)

就能確確實實以button.rx.tap的事件去取得subject最新的元素。

FlatMapLatest和WithLatestFrom

跟上面的範例有點相似,在進行refresh時,希望它能取得目前選擇的item去call API,簡化後的程式大概像下面這樣

// 錯誤示範
let selectedItem = BehaviorRelay<String>(value: "Item A")

let refreshSubject = PublishSubject<Void>()

let resultObservable = refreshSubject.flatMapLatest { selectedItem }

resultObservable
    .debug("Result")
    .subscribe()
    .disposed(by: disposeBag)
}

這樣會出什麼問題呢?

  1. 你點第一下、第二下...都會是正常的
  2. 當改變了selectedItem,像這樣selectedItem.accept("Item B"),也會使resultObservable發出元素,因為flatMapLatest特性,第一次Refresh時,就把元素投影到selectedItem,並將結果合併到另一條Observable,也就是resultObservable,所以,當selectedItem持續發出元素,其結果都會到resultObservable

所以還是要用withLatestFrom,把他修改成

let resultObservable = refreshSubject.withLatestFrom(selectedItem)

就符合我們預期的了!

到此為止,常用的operator都介紹完了,明天會介紹Error Handling Operators,就這樣,明天見。


上一篇
第 15 天 - Combining Observables(下)
下一篇
第 17 天 - Error Handling Operators (上)
系列文
RxSwift / 30天探索之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言