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事件

相关文章
|
6月前
|
机器学习/深度学习 数据挖掘 数据处理
从mice到missForest:常用数据插值方法优缺点
从mice到missForest:常用数据插值方法优缺点
272 1
|
监控 算法
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
独立成分分析(Independent Component Analysis,ICA)原理及代码实现
|
移动开发 文字识别 算法
论文推荐|[PR 2019]SegLink++:基于实例感知与组件组合的任意形状密集场景文本检测方法
本文简要介绍Pattern Recognition 2019论文“SegLink++: Detecting Dense and Arbitrary-shaped Scene Text by Instance-aware Component Grouping”的主要工作。该论文提出一种对文字实例敏感的自下而上的文字检测方法,解决了自然场景中密集文本和不规则文本的检测问题。
1946 0
论文推荐|[PR 2019]SegLink++:基于实例感知与组件组合的任意形状密集场景文本检测方法
|
4月前
|
机器学习/深度学习 Serverless 计算机视觉
【YOLOv8改进 - 注意力机制】Sea_Attention: Squeeze-enhanced Axial Attention,结合全局语义提取和局部细节增强
【YOLOv8改进 - 注意力机制】Sea_Attention: Squeeze-enhanced Axial Attention,结合全局语义提取和局部细节增强
|
5月前
|
机器学习/深度学习 算法 计算机视觉
【YOLOv8改进】CPCA(Channel prior convolutional attention)中的通道注意力,增强特征表征能力 (论文笔记+引入代码)
该专栏聚焦YOLO目标检测的创新改进与实战,介绍了一种针对医学图像分割的通道优先卷积注意力(CPCA)方法。CPCA结合通道和空间注意力,通过多尺度深度卷积提升性能。提出的CPCANet网络在有限计算资源下,于多个数据集上展现优越分割效果。代码已开源。了解更多详情,请访问提供的专栏链接。
|
5月前
|
机器学习/深度学习 编解码 算法
【YOLOv8改进】MLCA(Mixed local channel attention):混合局部通道注意力(论文笔记+引入代码)
**摘要:** 本文提出轻量级MLCA模块,结合通道、空间、局部及全局信息,提升网络表达效率。在MobileNet-Attention-YOLO(MAY)中应用MLCA,于PASCAL VOC和SMID数据集上对比SE和CA,mAP提升1.0%和1.5%。论文及代码链接提供。MLCA通过局部池化和反池化处理,增强通道交互和空间信息,实现更精确的目标检测。详情见YOLO改进与实战专栏。
|
6月前
|
数据可视化
R语言离散时间马尔可夫链(Markov chain)模型分类案例可视化分析
R语言离散时间马尔可夫链(Markov chain)模型分类案例可视化分析
|
6月前
|
资源调度 并行计算 数据可视化
【视频】马尔可夫链原理可视化解释与R语言区制转换MRS实例|数据分享
【视频】马尔可夫链原理可视化解释与R语言区制转换MRS实例|数据分享
|
6月前
|
计算机视觉
【YOLOv8改进】动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务
YOLO目标检测专栏介绍了DSCNet,它针对血管和道路等管状结构的分割任务进行优化。DSCNet采用动态蛇形卷积(DSConv)聚焦细长结构,多视角融合策略增强全局形态理解,且通过持久同调的连续性约束损失改善拓扑连续性。DSConv在2D和3D数据集上表现优于传统方法,实现更高精度和连续性。该技术已应用于yolov8,提升对管状结构的检测效果。
|
6月前
|
vr&ar
R语言如何做马尔可夫转换模型markov switching model
R语言如何做马尔可夫转换模型markov switching model