RxSwift map/ flatMpa/ flatMapLatest

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)換過后,就能直接獲取到可觀察序列中的元素(非可觀察序列)

用例

首先要知道的是flapMapflapMapLatest返回的是一個可觀察序列Observable,一個可觀察序列,相等是一個“輸出源”,可以進(jìn)行訂閱監(jiān)聽根據(jù)不同的輸出做不同的處理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容