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

相关文章
|
移动开发 前端开发 小程序
分享118个HTML公司企业模板,总有一款适合您
分享118个HTML公司企业模板,总有一款适合您
349 2
|
6月前
|
机器学习/深度学习 文字识别 自然语言处理
OCR技术:解锁文字识别的无限可能
OCR(光学字符识别)技术是数字化浪潮中的关键工具,可将纸质文档、手写笔记或复杂背景下的文字图像转化为可编辑文本。本文从图像采集、预处理、字符识别到文本校正,全面解析OCR技术的原理,并探讨其在智能办公、智慧交通、便捷生活等领域的广泛应用。未来,OCR将与自然语言处理、计算机视觉等技术深度融合,推动智能化和综合化发展。通过开放生态系统和政策支持,开发者可探索更多创新场景,如古籍数字化、盲人阅读等,为社会带来更多价值。
1519 57
|
8月前
|
数据采集 人工智能 数据可视化
SpatialLM:手机视频秒建3D场景!开源空间认知模型颠覆机器人训练
SpatialLM 是群核科技开源的空间理解多模态模型,能够通过普通手机拍摄的视频重建 3D 场景布局,赋予机器人类似人类的空间认知能力,适用于具身智能训练、自动导航、AR/VR 等领域。
679 5
SpatialLM:手机视频秒建3D场景!开源空间认知模型颠覆机器人训练
|
11月前
|
人工智能 关系型数据库 数据库
Perplexideez:开源本地 AI 搜索助手,智能搜索信息来源追溯
Perplexideez 是一款开源的本地 AI 搜索助手,旨在通过智能搜索和信息来源追溯功能,提升用户的搜索体验。它支持多用户、单点登录(SSO),并提供美观的搜索结果展示。Perplexideez 基于 Postgres 数据库,集成了 Ollama 或 OpenAI 兼容的端点,使用 SearXNG 实例进行网络搜索。
313 14
Perplexideez:开源本地 AI 搜索助手,智能搜索信息来源追溯
在进行多路直播时,如何保证不同视频源之间的同步性?
在进行多路直播时,如何保证不同视频源之间的同步性?
|
索引
RxSwift操作符take、skip、materialize、withLatestFrom、interval等的使用
RxSwift操作符take、skip、materialize、withLatestFrom、interval等的使用
457 1
|
程序员 索引
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
1434 0
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
|
Web App开发 JSON 小程序
苹果app开发apple-app-site-association文件配置
apple-app-site-association 是苹果的配置文件,用于建立app和网站关联,支持Universal Links,使点击网站链接能直接打开相应app内部页面。配置文件为JSON格式,需上传至服务器`.well-known`目录或根目录。通过检查三个链接来测试配置,确保Content-Type为`application/json`。成功配置后,点击链接能在iPhone备忘录或Safari中直接唤起app,但可能有24-48小时延迟。
|
文字识别 算法 TensorFlow
【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)
【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)
440 4
RxSwift操作符操作符map、flatMap、flatMapLatest、filter的使用与区别
RxSwift操作符操作符map、flatMap、flatMapLatest、filter的使用与区别
745 1