請各位務必要看這一篇,要否則後續的第六篇將會看得很難受。swift
顧名思義,合併Observable就是把多個Observable合併成一個。數組
那麼廢話很少說。開始吧bash
操做符能夠幫助你們建立新的序列,或者變化組合原有的序列,從而生成一個新的序列。
在RxSwfit 學習筆記(一)登陸校驗咱們提到的案例中,咱們有用到幾個操做符map、combineLatest
,這兩個就是操做符。函數
在RxSwift中的操做符有很是多。學習
看看這圖,就使人感受頭大。內容多,可是也只能一點一點的啃。測試
那今天咱們就先了解一下轉換操做符。ui
經過使用 merge
操做符你能夠將多個Observables
合併成一個,當某一個 Observable
發出一個元素時,他就將這個元素髮出。spa
若是,某一個Observable
發出一個 onError
事件,那麼被合併的 Observable
也會將它發出,而且當即終止序列。code
摘錄來自:RxSwift 中文文檔。cdn
案例
let disposeBag = DisposeBag()
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
Observable.of(subject1, subject2)
.merge()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("🅰️")
subject1.onNext("🅱️")
subject2.onNext("①")
subject2.onNext("②")
subject1.onNext("🆎")
subject2.onNext("③"
複製代碼
打印結果
🅰️
🅱️
①
②
🆎
③
複製代碼
讓兩個或多個 Observables
按順序串連起來
concat
操做符將多個 Observables
按順序串聯起來,當前一個 Observable
元素髮送完畢後,後一個Observable
才能夠開始發出元素。
concat
將等待前一個 Observable
產生完成事件後,纔對後一個 Observable
進行訂閱。若是後一個是「熱」 Observable
,在它前一個Observable
產生完成事件前,所產生的元素將不會被髮送出來。
startWith
和它十分類似。可是startWith
不是在後面添加元素,而是在前面插入元素。
merge
和它也是十分類似。merge
並非將多個 Observables
按順序串聯起來,而是將他們合併到一塊兒,不須要 Observables
按前後順序發出元素。
concat與merge的區別 concat必需要前一個Observables發送
onCompleted
,纔會發送後一個Observables發出來的元素。
案例
let disposeBag = DisposeBag()
let A = PublishSubject<String>()
let B = PublishSubject<String>()
Observable.of(A, B)
.concat()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
A.onNext("A-1")
A.onNext("A-2")
B.onNext("B-1")
A.onCompleted()
B.onNext("B-2")
A.onNext("A-3")
B.onNext("B-3")
複製代碼
打印結果
A-1
A-2
B-2
B-3
複製代碼
經過一個函數將多個 Observables
的元素組合起來,而後將每個組合的結果發出來。 zip
操做符將多個(最多不超過8個) Observables
的元素經過一個函數組合起來,而後將這個組合的結果發出來。它會嚴格的按照序列的索引數進行組合。例如,返回的Observable
的第一個元素,是由每個源Observables
的第一個元素組合出來的。它的第二個元素 ,是由每個源Observables
的第二個元素組合出來的。它的第三個元素 ,是由每個源 Observables
的第三個元素組合出來的,以此類推。它的元素數量等於源Observables
中元素數量最少的那個。
看着這一段的解釋挺繞的,仍是直接看案例會更快一點
經測試,zip就是會嚴格按照
一對一
、二對二
的格式來。
案例
let disposeBag = DisposeBag()
let first = PublishSubject<String>()
let second = PublishSubject<String>()
let third = PublishSubject<String>()
Observable.zip(first, second,third) { $0 + $1 + $2}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
first.onNext("1")
second.onNext("A")
third.onNext("-test")
third.onNext("-test2")
third.onNext("-test3")
first.onNext("2")
second.onNext("B")
second.onNext("C")
second.onNext("D")
first.onNext("3")
first.onNext("4")
複製代碼
打印結果
1A-test
2B-test2
3C-test3
複製代碼
由輸出結果咱們能夠看到,first跟second都發送了4個元素,而third只發了3個元素,那麼打印出來的也只有3個。 咱們能夠理解成木桶效應,一旦有其中一個Observables
發出的元素個數與其餘Observables
不對等,那麼能打印出來的結果就只有最少的個數的元素。
多個 Observables
中任何一個發出一個元素,就發出一個元素。這個元素是由這些Observables
中最新的元素,經過一個函數組合起來的
combineLatest
操做符將多個Observables
中最新的元素經過一個函數組合起來,而後將這個組合的結果發出來。這些源 Observables
中任何一個發出一個元素,他都會發出一個元素(前提是,這些 Observables
曾經發出過元素)。
直接看案例更容易懂。 案例
let disposeBag = DisposeBag()
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")
second.onNext("D")
first.onNext("3")
first.onNext("4")
複製代碼
打印結果
1A
2A
2B
2C
2D
3D
4D
複製代碼
在RxSwfit 學習筆記(一)登陸校驗中,咱們有用到combineLatest
就是校驗帳號與密碼的位數是否都超過5位,當兩個校驗都爲true的時候,再讓登陸按鈕enable。