RxSwift-高阶函数
RxSwift操作符
操作符可以帮助大家创建新的序列,或者变化组合原有的序列,从而生成一个新的序列。比如filter
过滤,map
转换等,具体可参考文档Operator - 操作符。
filter
,map
等操作符都是高阶函数,高阶函数接受一个或多个函数作为输入,最后输出一个函数。下面我们就以map
为例进行分析。
map原理分析
先来一段最简单的map
使用代码
let ob = Observable.of(1,2,3,4) ob.map { (number) -> Int in return number+2 } .subscribe{ print("\($0)") } .disposed(by: disposeBag)
|
查看map
函数,在注释部分,可以看到,具体实现在map文件中

extension ObservableType { public func map<Result>(_ transform: @escaping (Element) throws -> Result) -> Observable<Result> { return Map(source: self.asObservable(), transform: transform) } }
|
创建了一个Map
类,它是Producer
的子类,是不是突然很熟悉,在RxSwift-核心逻辑分析中,AnonymousObservable
也是Producer
的子类,它们应该有一些相似之处,我们来分析一下差别。
final private class Map<SourceType, ResultType>: Producer<ResultType> { typealias Transform = (SourceType) throws -> ResultType
private let source: Observable<SourceType>
private let transform: Transform
init(source: Observable<SourceType>, transform: @escaping Transform) { self.source = source self.transform = transform }
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { let sink = MapSink(transform: self.transform, observer: observer, cancel: cancel) let subscription = self.source.subscribe(sink) return (sink: sink, subscription: subscription) } }
|
- 多了
source
属性,用来存储原来的队列,transform
存储变换逻辑,也就是.map
后面的闭包return number+2
。
sink
也由AnonymousObservableSink
变成了MapSink
。
subscription
是source
的subscribe
返回值。
根据RxSwift-核心逻辑分析,我们已经知道,最后会调用MapSink
的on(_:)
方法。
final private class MapSink<SourceType, Observer: ObserverType>: Sink<Observer>, ObserverType { typealias Transform = (SourceType) throws -> ResultType
typealias ResultType = Observer.Element typealias Element = SourceType
private let transform: Transform
init(transform: @escaping Transform, observer: Observer, cancel: Cancelable) { self.transform = transform super.init(observer: observer, cancel: cancel) }
func on(_ event: Event<SourceType>) { switch event { case .next(let element): do { let mappedElement = try self.transform(element) self.forwardOn(.next(mappedElement)) } catch let e { self.forwardOn(.error(e)) self.dispose() } case .error(let error): self.forwardOn(.error(error)) self.dispose() case .completed: self.forwardOn(.completed) self.dispose() } } }
|
我们主要看看.next
的处理,此时element
是源序列的元素,也就是(1,2,3,4)
的元素,再调用transform
,也就是number+2
,最后经过transform
后的元素发送出去,这样,map
就完成了。
let mappedElement = try self.transform(element)
self.forwardOn(.next(mappedElement))
|
总结
- 高阶函数的订阅和响应逻辑和普通的序列是一样的。
- 不同的高阶函数逻辑由不同的
Producer
子类和不同的Sink
子类进行处理,保证了序列的灵活性和可扩展性。