特征序列(Traits)简介
RxSwift 里面 Observable 也存在一些特征序列,这些特征序列可以帮助我们更准确的描述序列。并且它们还可以给我们提供语法糖,让我们能够用更加优雅的方式书写代码。Single、Completable、Maybe都属于可监听序列(Observable),本文主要介绍这几个的特性以及使用方式以及部分源码解读:
01. Single
1. Single介绍
a. 要么只能发出一个元素
b. 要么产生一个error事件
c. 不会共享附加作用
一个比较常见的例子就是执行 HTTP 请求,然后返回一个应答或错误。不过你也可以用Single来描述任何只有一个元素的序列。
2. Single发送、订阅部分源码解读
从源码可以看到当create的时候只能发送success和failure,在success中调用on(.next(element)后,又立刻调用了on(.completed),则整个过程结束,为什么调用了on(.completed)最后却没收到完成信号?请继续向下看~
public static func create(subscribe: @escaping (@escaping SingleObserver) -> Disposable) -> Single<Element> { let source = Observable<Element>.create { observer in return subscribe { event in switch event { case .success(let element): observer.on(.next(element)) observer.on(.completed) case .failure(let error): observer.on(.error(error)) } } } return PrimitiveSequence(raw: source) }
@frozen public enum Result<Success, Failure> where Failure : Error { case success(Success) case failure(Failure) }
订阅部分仔细看stopped属性会发现,当接收到event后stopped由false改为了true,并且内部判断当为true的时候,直接return了,这就是为什么调用了on(.completed)最后却没收到完成信号?后面的信号Maybe也是类似设计,下文不再重复介绍;
再来看回调可以看到SingleEvent为Result的别名,Result只有success和failure两个值,而订阅的结果为next(Event)和error,不会再执行completed,最后订阅的结果包装成SingleEvent,供外界使用
public func subscribe(_ observer: @escaping (SingleEvent<Element>) -> Void) -> Disposable { var stopped = false return self.primitiveSequence.asObservable().subscribe { event in if stopped { return } stopped = true switch event { case .next(let element): observer(.success(element)) case .error(let error): observer(.failure(error)) case .completed: rxFatalErrorInDebug("Singles can't emit a completion event") } } }
3. Single的使用
single(.success(100)):发出一个100的元素
single(.failure(TestError.none)):发出一个error信号
Single<Int>.create { (single) -> Disposable in single(.success(100)) // single(.failure(TestError.none)) return Disposables.create() }.subscribe { (value) in print(value) } onFailure: { (error) in print(error) } onDisposed: { print("onDisposed") }.disposed(by: disposeBag)
运行结果:
100 onDisposed
02. Completable
1. Completable介绍
a. 不会发出任何元素
b. 发出一个completed事件或者一个error事件
c. 不会共享附加作用
Completable适用于那种你只关心任务是否完成,而不需要在意任务返回值的情况。它和Observable<Void>有点相似。
2. Completable订阅回调部分源码解读
从源码可以看到 CompletableEvent是一个枚举,有error和completed两个值,订阅的结果只有error和completed事件,没有next(Event)事件,并把订阅的结果包装成CompletableEvent,供外界使用
public enum CompletableTrait { } public typealias Completable = PrimitiveSequence<CompletableTrait, Swift.Never> @frozen public enum CompletableEvent { case error(Swift.Error) case completed }
extension PrimitiveSequenceType where Trait == CompletableTrait, Element == Swift.Never { public func subscribe(_ observer: @escaping (CompletableEvent) -> Void) -> Disposable { ... switch event { case .next: rxFatalError("Completables can't emit values") case .error(let error): observer(.error(error)) case .completed: observer(.completed) } }
3. Completable的使用
completable(.completed): 发出完成事件
completable(.error(TestError.none)):发出error事件
Completable.create(subscribe: { (completable) -> Disposable in completable(.completed) completable(.error(TestError.none)) return Disposables.create() }).subscribe { print("completed") } onError: { (error) in print(error) } onDisposed: { print("onDisposed") }.disposed(by: disposeBag)
运行结果:
completedon Disposed
03. Maybe
1. Maybe介绍
a. 发出一个元素或者一个completed事件或者一个error事件
b. 不会共享附加作用
如果你遇到那种可能需要发出一个元素,又可能不需要发出时,就可以使用Maybe
2. Maybe订阅回调部分源码解读
从源码可以看到CompletableEvent是一个枚举,有success,error和completed三个值,订阅的结果也有next(Event),error和completed事件,一旦收到订阅结果后,后面的就不会再执行,和上文Single设计类似,最后再订阅的结果包装成MaybeEvent,供外界使用
public enum MaybeTrait { } public typealias Maybe<Element> = PrimitiveSequence<MaybeTrait, Element> @frozen public enum MaybeEvent<Element> { case success(Element) case error(Swift.Error) case completed }
extension PrimitiveSequenceType where Trait == MaybeTrait { public typealias MaybeObserver = (MaybeEvent<Element>) -> Void ... public func subscribe(_ observer: @escaping (MaybeEvent<Element>) -> Void) -> Disposable { ... switch event { case .next(let element): observer(.success(element)) case .error(let error): observer(.error(error)) case .completed: observer(.completed) } } }
3. Maybe的使用
maybe(.success(200)): 发出一个元素
maybe(.completed): 发出完成事件
maybe(.error(TestError.none)):发出error事件
Maybe<Int>.create(subscribe: { (maybe) -> Disposable in maybe(.success(200)) // maybe(.completed) // maybe(.error(TestError.none)) return Disposables.create() }).subscribe { (element) in print(element) } onError: { (error) in print(error) } onCompleted: { print("completed") } onDisposed: { print("onDisposed") }.disposed(by: disposeBag)
运行结果:
200 onDisposed
总结
Single、Completable、Maybe均不会共享附加作用
1. Single要么只能发出一个元素、要么产生一个error事件
2. Completable不会发出任何元素,只能发出一个completed事件或者一个error事件
3.Maybe只能发出一个元素或者一个completed事件或者一个error事件