1.Observable 与订阅,Rx 世界的基石

发布时间:2026/10/22 17:49:36
1.Observable 与订阅,Rx 世界的基石 前言在上一篇中我们了解到Observable 可观察序列负责发射事件。 Observable 本质是一个“事件生产工厂”它可以发出三类事件.next(element)携带业务数据可以多次发送.error(Error)异常序列立刻终止后续不再发送任何事件.completed正常结束序列终止不再发送事件重点一旦序列触发 error / completed这条数据流就终结。Observable 分为冷、热。本篇我们全部围绕冷序列讲解没有订阅就不会执行每次订阅都会重新独立执行一遍。一、常见的 Observable 创建方法RxSwift内置大量构造方法我们逐个看附带代码示例。1. just只发射单个元素然后完成。let observable Observable.just(Hello Rx) observable.subscribe { event in print(event) }输出next(Hello Rx) completed适用场景包装单个固定值常量封装。2. of依次发射多个元素然后完成。let observable Observable.of(1,2,3) observable.subscribe { event in print(event) }输出next(1) next(2) next(3) completed3. from从数组中逐个取出元素发射。let observable Observable.from([10,20,30]) observable.subscribe { event in print(event) }区分of([1,2,3])是一次性把数组作为单个next发出from([1,2,3])遍历数组逐个发射元素。4. empty直接发送completed不发射任何 next。let observable ObservableInt.empty() observable.subscribe { event in print(event) }输出completed场景分支逻辑里返回一个空序列没有数据正常结束。5. never永不发射任何事件next/error/completed 都没有。let observable ObservableInt.never()适合测试或者代表无限持续的流极少业务使用。6. create手写自定义Observable最重要理解底层。create允许我们自己定义什么时候发送 next / error / completed。所有 Rx内置创建符底层本质都是基于create封装。// 手写一个自定义Observable let myObservable ObservableString.create { observer in // 这里订阅发生时代码才会执行【冷序列关键点】 print(✅ 开始生产事件) observer.onNext(第一条消息) observer.onNext(第二条消息) // observer.onError(NSError(domain: demo, code: -1)) observer.onCompleted() // 返回一个Disposable订阅销毁时执行 return Disposables.create { print(️ 订阅被释放) } } // 第一次订阅 myObservable.subscribe { event in print(订阅1收到\(event)) } print(分割线) // 第二次订阅 myObservable.subscribe { event in print(订阅2收到\(event)) }运行输出✅ 开始生产事件 订阅1收到next(第一条消息) 订阅1收到next(第二条消息) 订阅1收到completed ️ 订阅被释放 分割线 ✅ 开始生产事件 订阅2收到next(第一条消息) 订阅2收到next(第二条消息) 订阅2收到completed ️ 订阅被释放核心结论 每一次subscribe都会重新执行 create 内部的生产代码 这就是冷序列最直观的体现每个订阅者独立一份数据流。二、subscribe订阅连接 Observable 和 Observer。subscribe有多个重载方法从完整回调到简写形式。1.完整事件回调observable.subscribe { event in switch event { case .next(let value): print(next: \(value)) case .error(let err): print(error: \(err)) case .completed: print(completed) } }2.拆分四个单独闭包observable.subscribe( onNext: { value in print(onNext: \(value)) }, onError: { error in print(onError: \(error)) }, onCompleted: { print(onCompleted) }, onDisposed: { print(onDisposed订阅销毁) } )onNext接收正常数据onError接收错误收到error后序列终止不会再触发onNext/onCompletedonCompleted正常结束onDisposed无论正常完成、报错、手动取消最终都会执行做资源清理。坑提醒onError一旦触发onCompleted永远不会执行二选一。三、Disposable DisposeBagRx内存管理核心1. Disposable调用subscribe的返回值就是Disposable代表这次订阅资源。 你可以手动调用.dispose()提前终止数据流let disposable Observable.of(1,2,3).subscribe(onNext: { print($0) }) disposable.dispose() // 手动取消订阅但是项目里极少手动调用 dispose()太容易遗漏。2. DisposeBag销毁袋DisposeBag 相当于订阅的容器。把 disposabledisposed(by: bag)添加进去。 当 DisposeBag 实例被释放如ViewController销毁会自动批量调用所有订阅的 dispose。class DemoVC: UIViewController { // 定义销毁包页面生命周期持有 private let disposeBag DisposeBag() override func viewDidLoad() { super.viewDidLoad() Observable.of(A,B,C) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) // 加入销毁袋 } }黄金规则所有订阅必须交给 DisposeBag 管理。 如果不加入disposeBag对于无限序列比如持续的UI输入流会造成内存泄漏页面pop之后订阅继续存活。⚠️ 重要误区 ✅ 一个ViewController只需要一个disposeBag常规场景 ❌ 不要每次订阅都新建DisposeBag四、实战Demo验证冷序列特性我们用create的例子验证多次订阅会多次执行内部逻辑let obs ObservableInt.create { observer in print(开始执行序列逻辑) observer.onNext(1) observer.onCompleted() return Disposables.create() } print(准备第一次订阅) obs.subscribe(onNext: { print(sub1: \($0)) }) print(准备第二次订阅) obs.subscribe(onNext: { print(sub2: \($0)) })输出准备第一次订阅 开始执行序列逻辑 sub1: 1 准备第二次订阅 开始执行序列逻辑 sub2: 1两次订阅两次打印开始执行序列逻辑。这就是网络请求包装成Observable之后每次订阅都会重新发起网络请求的底层原因这个知识点面试高频。五、常见新手坑总结❌ 误以为Observable创建时就开始执行事件 ✅ 只有subscribe订阅之后才会执行生产逻辑冷序列❌ 忘记把订阅加入disposeBag无限流造成内存泄漏 ✅ 任何长期存在的数据流都要disposed(by: disposeBag)❌ 认为error和completed可以同时触发 ✅ error / completed 互斥任意一个发出序列终结❌ 混淆of([1,2,3])和from([1,2,3])✅ of传数组会把整个数组作为单个nextfrom会逐个遍历元素发射本篇小结Observable 发射三类事件next、error、completederror/completed会终止序列。常用创建符just / of / from / empty / nevercreate是自定义底层API。subscribe 建立订阅连接冷序列在订阅那一刻才开始执行。Disposable 代表订阅资源DisposeBag自动批量销毁订阅是Rx内存管理基石。冷序列每一次订阅独立从头执行网络请求Observable就是典型。思考题如果Observable发送了onErroronDisposed会不会执行我们用Moya封装的网络请求Observable是冷信号还是热信号多次订阅会发生什么empty 和 never 的核心区别是什么各自适用场景

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询