map操作符将源Observable的每个元素,通过提供的方法转换,然后返回含有转换后元素的Observable
Observable<Int>.of(1,2,3,4,5)
.map { index in
return index * 10
}
.subscribe { index in
print(index)
}.disposed(by: disposeBag)
输出结果
next(10)
next(20)
next(30)
next(40)
next(50)
completed
flatMap 操作符会对源Observable的每一个元素应用一个转换方法,将他们转换成Observable,然后将这些Observable的元素合并之后再发送出来,即将其降维成一个Observable序列
Observable<Int>.of(1,2,3,4,5)
.map { index in
return Observable.just(index)
}
.subscribe { index in
print(index)
}.disposed(by: disposeBag)
输出结果
next(RxSwift.(unknown context at $108e87ef8).Just<Swift.Int>)
next(RxSwift.(unknown context at $108e87ef8).Just<Swift.Int>)
next(RxSwift.(unknown context at $108e87ef8).Just<Swift.Int>)
next(RxSwift.(unknown context at $108e87ef8).Just<Swift.Int>)
next(RxSwift.(unknown context at $108e87ef8).Just<Swift.Int>)
completed
Observable<Int>.of(1,2,3,4,5)
.map { index in
return Observable.just(index)
}
.flatMap({ object in
return object
})
.subscribe { index in
print(index)
}.disposed(by: disposeBag)
上面这段代码.flatMap,其实是对map里面的对象事件进行解包的感觉,把原本是1,2,3,4,5的还原回来了
输出结果
next(1)
next(2)
next(3)
next(4)
next(5)
completed
Observable.of(1,2,3)
.flatMap { (value) -> Observable<Int> in
return Observable.just(value * 10)
}
.subscribe(onNext:{
print($0)
})
.disposed(by: bag)
/// 打印结果:
/// 10
/// 20
/// 30
flatMapLatest
: 当源序列有新的事件发生的时候,flatMapLatest会自动取消上一个是事件的订阅,转到新的事件的订阅上面
,而flatMap则会订阅全部
#案例4:
# 这种情况,flatMapLatest 与 flatMap 没什么不同,不能体现两者的区别
Observable.of(1,2,3)
.flatMapLatest { (value) -> Observable<Int> in
/// Observable.just 是一次性的可观察序列,发生完Event后,就直接Complete结束
/// 不能再发送第二个次的Event
/// 所以这不能很好的体现flatMapLatest的主要功能:取消上一次的事件订阅事件
return Observable.just(value * 10)
}
/// subscribe订阅的不是Observable.of(1,2,3)创建的可观察序列
/// 而是flatMap转变后的可观察序列
.subscribe(onNext:{
print($0)
})
.disposed(by: bag)
/// 打印结果:
/// 10
/// 20
/// 30
或者这样来
Observable<Int>.of(1,2,3,4,5,6)
.flatMapLatest { value in
return Signal.just(value)
}
.subscribe { objc in
print(objc)
}.disposed(by: disposeBag)
/// 返回的结果是一样的
flatMapLatest 与 flatMap 使用区别案例
struct Player {
var score : BehaviorRelay<Int>
}
flatMap的实现
let aPlayer = Player(score: BehaviorRelay(value: 1))
let bPlayer = Player(score: BehaviorRelay(value: 2))
let players = PublishSubject<Player>()
players.asObserver()
.flatMap { (player) -> Observable<Int> in
player.score.asObservable()
}
/// subscribe 订阅的不是players
/// 而是players事件中包含的每一个player.score
.subscribe(onNext:{
print($0)
})
.disposed(by: bag)
/// players 发送Event,对象是aPlayer,因此aPlayer被订阅了
players.onNext(aPlayer)
/// aPlayer对象,发出事件,因为被订阅了,所以能接收到并打印
aPlayer.score.accept(3)
/// players 再次发出Event,对象是bPlayer,因此bPlayer也被订阅了
/// 但是aPlayer的订阅并没有被取消
players.onNext(bPlayer)
/// aPlayer对象再发出事件,依然能被接收和打印
aPlayer.score.accept(4)
/// 打印结果:
1
3
2
4
flatMapLatest的实现
let aPlayer = Player(score: BehaviorRelay(value: 1))
let bPlayer = Player(score: BehaviorRelay(value: 2))
let players = PublishSubject<Player>()
players.asObserver()
.flatMapLatest { (player) -> Observable<Int> in
player.score.asObservable()
}
.subscribe(onNext:{
print($0)
})
.disposed(by: bag)
players.onNext(aPlayer)
aPlayer.score.accept(3)
/// players发起一个新的事件,会对bPlayer订阅,并且同时取消上一次Event发送过来的aPlayer对象
players.onNext(bPlayer)
/// aPlayer被取消订阅了,所以没有打印
aPlayer.score.accept(4)
/// 打印结果:
1
3
2
总结:如果flatMap接收事件Event包裹的元素也是一个Observable,并且不希望保存上一次的订阅,则可以使用flatMapLatest
勘误
:map、flatMap、flatMapLatest最终返回的都是一个可观察序列(比如Observable、Driver),不同的
是map闭合函数返回的值,map函数会自动包装一层可观察序列
而flatMap
、flatMapLatest
闭合函数返回的必须是一个可观察序列,与map作用最大的区别
是如果源可观察序列携带的也是可观察序列元素,那么flatMap、flatMapLatest就可以将闭合函数入参的可观察序列直接返回,这样达到一个“降维”的效果,订阅flatMap、flatMapLatest转换过后,就能直接获取到可观察序列中的元素(非可观察序列)
用例
首先要知道的是
flapMap
和flapMapLatest
返回的是一个可观察序列Observable
,一个可观察序列,相等是一个“输出源”
,可以进行订阅监听
,根据不同的输出做不同的处理