map操作符將源Observable的每個元素,通過提供的方法轉(zhuǎn)換,然后返回含有轉(zhuǎn)換后元素的Observable
Observable<Int>.of(1,2,3,4,5)
.map { index in
return index * 10
}
.subscribe { index in
print(index)
}.disposed(by: disposeBag)
輸出結(jié)果
next(10)
next(20)
next(30)
next(40)
next(50)
completed
flatMap 操作符會對源Observable的每一個元素應(yīng)用一個轉(zhuǎn)換方法,將他們轉(zhuǎn)換成Observable,然后將這些Observable的元素合并之后再發(fā)送出來,即將其降維成一個Observable序列
Observable<Int>.of(1,2,3,4,5)
.map { index in
return Observable.just(index)
}
.subscribe { index in
print(index)
}.disposed(by: disposeBag)
輸出結(jié)果
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,其實(shí)是對map里面的對象事件進(jìn)行解包的感覺,把原本是1,2,3,4,5的還原回來了
輸出結(jié)果
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)
/// 打印結(jié)果:
/// 10
/// 20
/// 30
flatMapLatest: 當(dāng)源序列有新的事件發(fā)生的時候,flatMapLatest會自動取消上一個是事件的訂閱,轉(zhuǎn)到新的事件的訂閱上面,而flatMap則會訂閱全部
#案例4:
# 這種情況,flatMapLatest 與 flatMap 沒什么不同,不能體現(xiàn)兩者的區(qū)別
Observable.of(1,2,3)
.flatMapLatest { (value) -> Observable<Int> in
/// Observable.just 是一次性的可觀察序列,發(fā)生完Event后,就直接Complete結(jié)束
/// 不能再發(fā)送第二個次的Event
/// 所以這不能很好的體現(xiàn)flatMapLatest的主要功能:取消上一次的事件訂閱事件
return Observable.just(value * 10)
}
/// subscribe訂閱的不是Observable.of(1,2,3)創(chuàng)建的可觀察序列
/// 而是flatMap轉(zhuǎn)變后的可觀察序列
.subscribe(onNext:{
print($0)
})
.disposed(by: bag)
/// 打印結(jié)果:
/// 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)
/// 返回的結(jié)果是一樣的
flatMapLatest 與 flatMap 使用區(qū)別案例
struct Player {
var score : BehaviorRelay<Int>
}
flatMap的實(shí)現(xiàn)
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 發(fā)送Event,對象是aPlayer,因此aPlayer被訂閱了
players.onNext(aPlayer)
/// aPlayer對象,發(fā)出事件,因?yàn)楸挥嗛喠?,所以能接收到并打?aPlayer.score.accept(3)
/// players 再次發(fā)出Event,對象是bPlayer,因此bPlayer也被訂閱了
/// 但是aPlayer的訂閱并沒有被取消
players.onNext(bPlayer)
/// aPlayer對象再發(fā)出事件,依然能被接收和打印
aPlayer.score.accept(4)
/// 打印結(jié)果:
1
3
2
4
flatMapLatest的實(shí)現(xiàn)
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發(fā)起一個新的事件,會對bPlayer訂閱,并且同時取消上一次Event發(fā)送過來的aPlayer對象
players.onNext(bPlayer)
/// aPlayer被取消訂閱了,所以沒有打印
aPlayer.score.accept(4)
/// 打印結(jié)果:
1
3
2
總結(jié):如果flatMap接收事件Event包裹的元素也是一個Observable,并且不希望保存上一次的訂閱,則可以使用flatMapLatest
勘誤:map、flatMap、flatMapLatest最終返回的都是一個可觀察序列(比如Observable、Driver),不同的是map閉合函數(shù)返回的值,map函數(shù)會自動包裝一層可觀察序列而flatMap、flatMapLatest閉合函數(shù)返回的必須是一個可觀察序列,與map作用最大的區(qū)別是如果源可觀察序列攜帶的也是可觀察序列元素,那么flatMap、flatMapLatest就可以將閉合函數(shù)入?yún)⒌目捎^察序列直接返回,這樣達(dá)到一個“降維”的效果,訂閱flatMap、flatMapLatest轉(zhuǎn)換過后,就能直接獲取到可觀察序列中的元素(非可觀察序列)
用例
首先要知道的是
flapMap和flapMapLatest返回的是一個可觀察序列Observable,一個可觀察序列,相等是一個“輸出源”,可以進(jìn)行訂閱監(jiān)聽,根據(jù)不同的輸出做不同的處理