美文网首页
Transforming Operators of flatMa

Transforming Operators of flatMa

作者: 狼性刀锋 | 来源:发表于2018-10-15 16:24 被阅读24次

    flatMap

    官方示例

    example("flatMap and flatMapLatest") {
        let disposeBag = DisposeBag()
        
        struct Player {
            var score: Variable<Int>
        }
        
        let 👦🏻 = Player(score: Variable(80))
        let 👧🏼 = Player(score: Variable(90))
        
        let player = Variable(👦🏻)
        
        player.asObservable()
            .flatMap { $0.score.asObservable() } // Change flatMap to flatMapLatest and observe change in printed output
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)
        
        👦🏻.score.value = 85
        
        player.value = 👧🏼
        
        👦🏻.score.value = 95 // Will be printed when using flatMap, but will not be printed when using flatMapLatest
        
        👧🏼.score.value = 100
    }
    
    // out log 
    --- flatMap and flatMapLatest example ---
    ℹ️ [DEPRECATED] `Variable` is planned for future deprecation. Please consider `BehaviorRelay` as a replacement. Read more at: https://git.io/vNqvx
    80
    85
    90
    95
    100
    
    

    函数原型

    extension ObservableType {
    
        /**
         Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
    
         - seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html)
    
         - parameter selector: A transform function to apply to each element.
         - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.
         */
        public func flatMap<O: ObservableConvertibleType>(_ selector: @escaping (E) throws -> O)
            -> Observable<O.E> {
                return FlatMap(source: asObservable(), selector: selector)
        }
    
    }
    

    FlatMap 实现

    final fileprivate class FlatMap<SourceElement, SourceSequence: ObservableConvertibleType>: Producer<SourceSequence.E> {
        typealias Selector = (SourceElement) throws -> SourceSequence
    
        private let _source: Observable<SourceElement>
        
        private let _selector: Selector
    
        init(source: Observable<SourceElement>, selector: @escaping Selector) {
            _source = source
            _selector = selector
        }
        
        override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == SourceSequence.E {
            let sink = FlatMapSink(selector: _selector, observer: observer, cancel: cancel)
            let subscription = sink.run(_source)
            return (sink: sink, subscription: subscription)
        }
    }
    
    

    核心实现仍然在Sink之中

    
    fileprivate final class FlatMapSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType> : MergeSink<SourceElement, SourceSequence, Observer> where Observer.E == SourceSequence.E {
        typealias Selector = (SourceElement) throws -> SourceSequence
    
        private let _selector: Selector
    
        init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) {
            _selector = selector
            super.init(observer: observer, cancel: cancel)
        }
    
        override func performMap(_ element: SourceElement) throws -> SourceSequence {
            return try _selector(element)
        }
    }
    
    
    
    fileprivate final class FlatMapSink<SourceElement, SourceSequence: ObservableConvertibleType, Observer: ObserverType> : MergeSink<SourceElement, SourceSequence, Observer> where Observer.E == SourceSequence.E {
        typealias Selector = (SourceElement) throws -> SourceSequence
    
        private let _selector: Selector
    
        init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) {
            _selector = selector
            super.init(observer: observer, cancel: cancel)
        }
    
        override func performMap(_ element: SourceElement) throws -> SourceSequence {
            return try _selector(element)
        }
    }
    
    

    FlatMapSink 继承于MergeSink, 那么 FlatMap 操作只是个皮, Merge 操作才是骨,
    Original Observable 每次产生的Next事件, 都会被_selector 转换成一个新的Observable, 然后由 MergeSinkIter 订阅该 Observable, 最后传递给 FlatMapSink。 简单验证一下.

        func testFlatMap() {
            let disposeBag = DisposeBag()
            
            let aPublishSubject = PublishSubject<String>()
            
            let bPublishSubject = PublishSubject<String>()
            let cPublishSubject = PublishSubject<String>()
            
            
            
            aPublishSubject.asObservable()
                .flatMap { $0 == "1" ? bPublishSubject : cPublishSubject }
                .subscribe(onNext: { print($0) })
                .disposed(by: disposeBag)
            
            aPublishSubject.onNext("1")
            aPublishSubject.onNext("2")
            
            bPublishSubject.onNext("b")
            cPublishSubject.onNext("c")
        }
    
    
    
    // out put log 
    b
    c
    

    简析:在aPublishSubject onNext(1) 和 onNext(2) 之后,那么 实际就成功订阅了bPublishSubject和cPublishSubject, 这两个PublishSubject发出的next事件最终都会被用户订阅到。所以flatMap 不仅仅是将事件转换为新的Observable, 而且还隐含着Merge操作。

    flatMapLatest

    代码示例就不写了,只需要简单的将 flatMap 替换成 flatMapLatest 即可

        public func flatMapLatest<O: ObservableConvertibleType>(_ selector: @escaping (E) throws -> O)
            -> Observable<O.E> {
                return FlatMapLatest(source: asObservable(), selector: selector)
        }
    
    
    // FlatMapLatest
    final fileprivate class FlatMapLatest<SourceType, S: ObservableConvertibleType> : Producer<S.E> {
        typealias Selector = (SourceType) throws -> S
    
        fileprivate let _source: Observable<SourceType>
        fileprivate let _selector: Selector
    
        init(source: Observable<SourceType>, selector: @escaping Selector) {
            _source = source
            _selector = selector
        }
    
        override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == S.E {
            let sink = MapSwitchSink<SourceType, S, O>(selector: _selector, observer: observer, cancel: cancel)
            let subscription = sink.run(_source)
            return (sink: sink, subscription: subscription)
        }
    }
    
    
    // MapSwitchSink
    final fileprivate class MapSwitchSink<SourceType, S: ObservableConvertibleType, O: ObserverType> : SwitchSink<SourceType, S, O> where O.E == S.E {
        typealias Selector = (SourceType) throws -> S
    
        fileprivate let _selector: Selector
    
        init(selector: @escaping Selector, observer: O, cancel: Cancelable) {
            _selector = selector
            super.init(observer: observer, cancel: cancel)
        }
    
        override func performMap(_ element: SourceType) throws -> S {
            return try _selector(element)
        }
    }
    
    

    MapSwitchSink 继承于 SwitchSink, 与 SwitchIdentitySink 唯一不一样的地方在于performMap。 所以 FlatMapLatest 其实和 SwitchLatest是一样的机制, 永远只订阅最新的Observable

    相关文章

      网友评论

          本文标题:Transforming Operators of flatMa

          本文链接:https://www.haomeiwen.com/subject/ljnfzftx.html