RxSwift map/ flatMpa/ flatMapLatest

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函数会自动包装一层可观察序列flatMapflatMapLatest闭合函数返回的必须是一个可观察序列,与map作用最大的区别是如果源可观察序列携带的也是可观察序列元素,那么flatMap、flatMapLatest就可以将闭合函数入参的可观察序列直接返回,这样达到一个“降维”的效果,订阅flatMap、flatMapLatest转换过后,就能直接获取到可观察序列中的元素(非可观察序列)

用例

首先要知道的是flapMapflapMapLatest返回的是一个可观察序列Observable,一个可观察序列,相等是一个“输出源”,可以进行订阅监听根据不同的输出做不同的处理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容