请各位务必要看这一篇,要不然后续的第六篇将会看得很难受。
顾名思义,合并Observable就是把多个Observable合并成一个。
那么废话不多说。开始吧
什么是操作符?
操作符可以帮助大家创建新的序列,或者变化组合原有的序列,从而生成一个新的序列。
在RxSwfit 学习笔记(一)登录校验我们提到的案例中,我们有用到几个操作符map、combineLatest
,这两个就是操作符。
在RxSwift中的操作符有非常多。
看看这图,就令人感觉头大。内容多,但是也只能一点一点的啃。
那今天我们就先了解一下转换操作符。
merge
通过使用 merge
操作符你可以将多个Observables
合并成一个,当某一个 Observable
发出一个元素时,他就将这个元素发出。
如果,某一个Observable
发出一个 onError
事件,那么被合并的 Observable
也会将它发出,并且立即终止序列。
摘录来自:RxSwift 中文文档。
案例
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("③"
打印结果
🅰️
🅱️
①
②
🆎
③
concat
让两个或多个 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
zip
通过一个函数将多个 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
不对等,那么能打印出来的结果就只有最少的个数的元素。
combineLatest
多个 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。