转换操作符
map
通过一个转换函数,将 Observable 的每个元素转换一遍
案例
class SixthViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let arr:[Dictionary<String,Any>] = [
["name":"张三","age":23],
["name":"李四","age":33],
["name":"王五","age":22],]
Observable.from(arr)
.map { Person.init(dic: $0) }
.subscribe(onNext: { print($0.name!) })
.disposed(by: disposeBag)
}
struct Person {
var name:String!
var age:Int!
init(dic:Dictionary<String,Any>) {
self.name = dic["name"] as? String
self.age = dic["age"] as? Int
}
}
}
flatMap
将 Observable 的元素转换成其他的 Observable,然后将这些Observables 合并。
将Observable的元素转换成其他的Observable。(如:案例中C的元素是A)
flatMap 操作符将源 Observable的每一个元素应用一个转换方法,将他们转换成Observables。 然后将这些 Observables的元素合并之后再发送出来。
这个操作符是非常有用的,例如,当 Observable的元素本身拥有其他的Observable时,你可以将所有子Observables 的元素发送出来。
官方案例


在学的过程,我看《RxSwift中文文档》里面的案例很难受,啪啪啪打脸啊。
案例中他用了Variable,可是在前面他自己又提到了Variable已经弃用了,然后我看着这个案例我就很难受,觉得这对一名新手来说非常不友好。那怎么办呢?
我想我会照成困扰的原因还是在于这句话。
将 Observable的元素转换成其他的 Observable,然后将这些Observables合并
合并是什么意思?
我发现我跳过了很重要的一部分,就是合并,本来这篇文章是比第五篇出来得早的,但是我觉得并没有理解它,还是仔细把第五篇补上。学习顺序还是很重要的!
所以看到这里的如果没看过第五篇还是去看一下。
稍微理清楚了,这里我想了一个比方,可能不太准确。
这个理解起来真的非常的恶心,想了半天想了这么一个例子。
C是一个领班,A和B是工人,领班通过
flatMap把A和B招进来,然后当AB工作时(onNext),领班就能知道A和B都做了什么。
案例
let A = BehaviorSubject(value: "A的默认消息")
let B = BehaviorSubject(value: "B的默认消息")
Observable.of(A,B)//同时观察了A,B
.flatMap {$0} //将Observable的元素转换成其他的Observable",把对 A/B 的观察" 转成 "A/B 观察的字符串"
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
A.onNext("A-2")
A.onNext("A-3")
B.onNext("B-2")
B.onNext("B-3")
B.onNext("B-4")
打印结果
A的默认消息
B的默认消息
A-2
A-3
B-2
B-3
B-4
flatMapLatest
将 Observable 的元素转换成其他的Observable,然后取这些 Observables中最新的一个。
flatMapLatest操作符将源Observable 的每一个元素应用一个转换方法,将他们转换成Observables。一旦转换出一个新的 Observable,就只发出它的元素,旧的 Observables的元素将被忽略掉。
理解了flatMap之后再来理解这个flatMapLatest就比较容易了
A比B先进工厂 ,在B还没进工厂前,领班C需要看着A。B进工厂后,领班觉得A做得熟练了,就不管A了,只看着B。
案例 跟flatMap 的案例只是换了一下单词flatMapLatest
let A = BehaviorSubject(value: "A的默认消息")
let B = BehaviorSubject(value: "B的默认消息")
Observable.of(A,B)
.flatMapLatest {$0}
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
A.onNext("A-2")
A.onNext("A-3")
B.onNext("B-2")
B.onNext("B-3")
B.onNext("B-4")
打印结果
A的默认消息
B的默认消息
B-2
B-3
B-4
当观察者从A转到B的时候,就不再观察A发出来的元素。
concatMap
将 Observable 的元素转换成其他的 Observable,然后将这些 Observables 串连起来
concatMap操作符将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。然后让这些Observables 按顺序的发出元素,当前一个 Observable 元素发送onCompleted()后,后一个 Observable 才可以开始发出元素。等待前一个Observable 产生完成事件后,才对后一个 Observable 进行订阅。
在第一个Observable 元素
onCompleted()后,第二个Observable 元素可以发出第一个结束前发出的最后一个onNext()
案例 这个案例跟上两个的区别是多了一个onCompleted()
let A = BehaviorSubject(value: "A的默认消息")
let B = BehaviorSubject(value: "B的默认消息")
Observable.of(A,B)
.concatMap {$0}
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
A.onNext("A-2")
B.onNext("B-2")
B.onNext("B-3")
A.onCompleted()
A.onNext("A-3")
B.onNext("B-4")
打印结果
A的默认消息
A-2
B-3
B-4
一旦A发出onCompleted(),会发出B先前发出的最后一个元素。
scan
持续的将Observable的每一个元素应用一个函数,然后发出每一次函数返回的结果。
scan操作符将对第一个元素应用一个函数,将结果作为第一个元素发出。然后,将结果作为参数填入到第二个元素的应用函数中,创建第二个元素。以此类推,直到遍历完全部的元素。
案例
let disposeBag = DisposeBag()
Observable.of(10, 100, 1000)
.scan(0) { aValue, newValue in
aValue + newValue
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
打印结果
10
110
1110