RxSwift特征序列Single、Maybe、Completable的使用

简介: RxSwift特征序列Single、Maybe、Completable的使用

特征序列(Traits)简介

RxSwift 里面 Observable 也存在一些特征序列,这些特征序列可以帮助我们更准确的描述序列。并且它们还可以给我们提供语法糖,让我们能够用更加优雅的方式书写代码。SingleCompletableMaybe都属于可监听序列(Observable),本文主要介绍这几个的特性以及使用方式以及部分源码解读


01. Single

1. Single介绍

a. 要么只能发出一个元素

b. 要么产生一个error事件

c. 不会共享附加作用

一个比较常见的例子就是执行 HTTP 请求,然后返回一个应答或错误。不过你也可以用Single来描述任何只有一个元素的序列。


2. Single发送、订阅部分源码解读

从源码可以看到当create的时候只能发送successfailure,在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属性会发现,当接收到eventstoppedfalse改为了true,并且内部判断当为true的时候,直接return了,这就是为什么调用了on(.completed)最后却没收到完成信号?后面的信号Maybe也是类似设计,下文不再重复介绍;

再来看回调可以看到SingleEventResult的别名,Result只有successfailure两个值,而订阅的结果为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是一个枚举,有errorcompleted两个值,订阅的结果只有errorcompleted事件,没有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,errorcompleted三个值,订阅的结果也有next(Event)errorcompleted事件,一旦收到订阅结果后,后面的就不会再执行,和上文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、CompletableMaybe不会共享附加作用

1. Single要么只能发出一个元素、要么产生一个error事件

2. Completable不会发出任何元素,只能发出一个completed事件或者一个error事件

3.Maybe只能发出一个元素或者一个completed事件或者一个error事件

相关文章
|
2月前
|
机器学习/深度学习 数据挖掘 数据处理
从mice到missForest:常用数据插值方法优缺点
从mice到missForest:常用数据插值方法优缺点
41 1
|
监控 算法
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
|
14天前
|
vr&ar
R语言如何做马尔可夫转换模型markov switching model
R语言如何做马尔可夫转换模型markov switching model
|
15天前
|
vr&ar
R语言如何做马尔科夫转换模型markov switching model
R语言如何做马尔科夫转换模型markov switching model
16 0
|
15天前
R语言中的马尔科夫机制转换(Markov regime switching)模型
R语言中的马尔科夫机制转换(Markov regime switching)模型
14 0
|
3月前
|
机器学习/深度学习 移动开发 安全
【现代密码学】笔记6--伪随机对象的理论构造《introduction to modern cryphtography》
【现代密码学】笔记6--伪随机对象的理论构造《introduction to modern cryphtography》
26 0
2022小美赛B题The Genetic Process of Sequences序列的遗传过程思路分享
2022小美赛B题The Genetic Process of Sequences序列的遗传过程思路分享
2022小美赛B题The Genetic Process of Sequences序列的遗传过程思路分享
|
算法
杭电oj HDOJ 2050 折线分割平面(递推)算法 数学逻辑(由分割平面转化而来)
杭电oj HDOJ 2050 折线分割平面(递推)算法 数学逻辑(由分割平面转化而来)
98 0
杭电oj HDOJ 2050 折线分割平面(递推)算法 数学逻辑(由分割平面转化而来)
|
机器学习/深度学习 数据可视化 算法
Paper:《Peeking Inside the Black Box: Individual Conditional Expectation-窥视黑盒内部:用个体条件期望图可视化统计学习》翻译与解读
Paper:《Peeking Inside the Black Box: Individual Conditional Expectation-窥视黑盒内部:用个体条件期望图可视化统计学习》翻译与解读
Paper:《Peeking Inside the Black Box: Individual Conditional Expectation-窥视黑盒内部:用个体条件期望图可视化统计学习》翻译与解读
|
机器学习/深度学习 编解码 数据可视化
CVPR2021 | SETR: 使用 Transformer 从序列到序列的角度重新思考语义分割
本文介绍了一篇CVPR2021的语义分割论文,论文将语义分割视为序列到序列的预测任务,基于transformer作为编码器,介绍了三种解码器方式,选择其中效果最好的解码器方式与transformer编码器组成了一个新的SOTA模型--SETR。
CVPR2021 | SETR: 使用 Transformer 从序列到序列的角度重新思考语义分割