RxSwift4-Subjects介绍

作者: 浮华_du | 来源:发表于2021-04-15 16:44 被阅读0次

看了前面介绍的创建Observable的方式, 我们应该会想,在项目的实际使用中,大多数情况都是预先不知道序列值的.比如:我们要订阅文本框内容输入的变化.
这个时候,RxSwift为我们提供了Subjects,既是订阅者,也是 Observable.
Subjects分为四种类型: PublishSubject、BehaviorSubject、ReplaySubject、Variable(BehaviorRelay).我们分别来介绍下他们的用法及区别:

1. PublishSubject

  • 无需初始值
  • 订阅者只能收到他们 订阅后 发出的Event.
let subject = PublishSubject<String>()
        subject.onNext("第一条消息")
        subject.subscribe(onNext: { string in
            print("第1次订阅:", string)
        }, onCompleted:{
            print("第1次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第二条消息")
         
        subject.subscribe(onNext: { string in
            print("第2次订阅:", string)
        }, onCompleted:{
            print("第2次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第三条消息")
         
        //让subject结束
        subject.onCompleted()
         
        //subject结束后会发出.next事件了。
        subject.onNext("第四条消息")
         
        subject.subscribe(onNext: { string in
            print("第3次订阅:", string)
        }, onCompleted:{
            print("第3次订阅:onCompleted")
        }).disposed(by: disposeBag)

//第1次订阅: 第二条消息
//第1次订阅: 第三条消息
//第2次订阅: 第三条消息
//第1次订阅:onCompleted
//第2次订阅:onCompleted
//第3次订阅:onCompleted

2. BehaviorSubject

  • 需要传入初始值
  • 当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个及之后 发出的新的 event。
let subject = BehaviorSubject(value: "初始消息")
        subject.onNext("第一条消息")
        subject.subscribe(onNext: { string in
            print("第1次订阅:", string)
        }, onCompleted:{
            print("第1次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第二条消息")
         
        subject.subscribe(onNext: { string in
            print("第2次订阅:", string)
        }, onCompleted:{
            print("第2次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第三条消息")
         
        //让subject结束
        subject.onCompleted()
         
        //subject完成后会发出.next事件了。
        subject.onNext("第四条消息")
         
        subject.subscribe(onNext: { string in
            print("第3次订阅:", string)
        }, onCompleted:{
            print("第3次订阅:onCompleted")
        }).disposed(by: disposeBag)

//第1次订阅: 第一条消息
//第1次订阅: 第二条消息
//第2次订阅: 第二条消息
//第1次订阅: 第三条消息
//第2次订阅: 第三条消息
//第1次订阅:onCompleted
//第2次订阅:onCompleted
//第3次订阅:onCompleted

3.ReplaySubject

  • 需要一个初始bufferSize(缓存的event的个数)
  • 当一个订阅者来订阅它的时候,这个订阅者会立即收到 ReplaySubject 最近两个及之后 发出的新的 event。

例如下面代码, 一个 ReplaySubject 的 bufferSize 设置为 2,它发出了 4 个 .next 的 event("第五条消息"是在结束后.onNext的,不会发出),那么它会将后两个(最近的两个-bufferSize个数)event 给缓存起来。

此时如果有一个 subscriber 订阅了这个 ReplaySubject,那么这个 subscriber 就会立即收到前面缓存的两个.next 的 event。(例如:第三次订阅,收到了前面缓存的最近的两个消息2,3)及之后发出的4消息)

如果一个 subscriber 订阅已经结束的 ReplaySubject,除了会收到缓存的 .next 的 event外,还会收到那个终结的 .error 或者 .complete 的event。(第五次订阅)
//第一次订阅 总共收到了 1,+2,3,4消息
//第二次订阅 总共收到了 1,2,+3,4消息
//第三次订阅 总共收到了 2,3,+4消息
//第四次订阅 总共收到了 3,4+无消息
//第五次订阅 总共收到了 3,4+无消息

let subject = ReplaySubject<String>.create(bufferSize: 2)
        subject.onNext("第一条消息")
        subject.subscribe(onNext: { string in
            print("第1次订阅:", string)
        }, onCompleted:{
            print("第1次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第二条消息")
         
        subject.subscribe(onNext: { string in
            print("第2次订阅:", string)
        }, onCompleted:{
            print("第2次订阅:onCompleted")
        }).disposed(by: disposeBag)
         
        subject.onNext("第三条消息")
         
        subject.subscribe(onNext: { string in
            print("第3次订阅:", string)
        }, onCompleted:{
            print("第3次订阅:onCompleted")
        }).disposed(by: disposeBag)
        
        subject.onNext("第四条消息")
        
        subject.subscribe(onNext: { string in
            print("第4次订阅:", string)
        }, onCompleted:{
            print("第4次订阅:onCompleted")
        }).disposed(by: disposeBag)
        
        //让subject结束
        subject.onCompleted()
         
        //subject完成后就不会发出.next事件了。
        subject.onNext("第五条消息")
        
        subject.subscribe(onNext: { string in
            print("第5次订阅:", string)
        }, onCompleted:{
            print("第5次订阅:onCompleted")
        }).disposed(by: disposeBag)
//第1次订阅: 第一条消息
//第1次订阅: 第二条消息
//第2次订阅: 第一条消息
//第2次订阅: 第二条消息
//第1次订阅: 第三条消息
//第2次订阅: 第三条消息
//第3次订阅: 第二条消息
//第3次订阅: 第三条消息
//第1次订阅: 第四条消息
//第2次订阅: 第四条消息
//第3次订阅: 第四条消息
//第4次订阅: 第三条消息
//第4次订阅: 第四条消息
//第1次订阅:onCompleted
//第2次订阅:onCompleted
//第3次订阅:onCompleted
//第4次订阅:onCompleted
//第5次订阅: 第三条消息
//第5次订阅: 第四条消息
//第5次订阅:onCompleted


4. Variable => BehaviorRelay

  • Variable 其实就是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
  • Variable 具有 BehaviorSubject 的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
  • 不同的是,Variable 还会把当前发出的值保存为自己的状态。同时它会在销毁时自动发送 .complete的 event,不需要也不能手动给 Variables 发送 completed或者 error 事件来结束它
    简单地说就是 Variable 有一个 value 属性,我们改变这个 value 属性的值就相当于调用一般 Subjects 的 onNext() 方法,而这个最新的 onNext() 的值就被保存在 value 属性里了,直到我们再次修改它。
    Variable已经被BehaviorRelay取代
 let variable = Variable("初始消息")
        
        variable.value = "第一条消息"
        //第1次订阅
        variable.asObservable().subscribe {
            print("第1次订阅:", $0)
        }.disposed(by: disposeBag)
        
        variable.value = "第二条消息"
        //第2次订阅
        variable.asObservable().subscribe {
            print("第2次订阅:", $0)
        }.disposed(by: disposeBag)
        
        variable.value = "第三条消息"
        variable.asObservable().subscribe {
            print("第3次订阅:", $0)
        }.disposed(by: disposeBag)

//ℹ️ [DEPRECATED] `Variable` is planned for future deprecation. Please consider `BehaviorRelay` as a replacement. Read more at: https://git.io/vNqvx
//第1次订阅: next(第一条消息)
//第1次订阅: next(第二条消息)
//第2次订阅: next(第二条消息)
//第1次订阅: next(第三条消息)
//第2次订阅: next(第三条消息)
//第3次订阅: next(第三条消息)
//第1次订阅: completed
//第2次订阅: completed
//第3次订阅: completed

5. BehaviorRelay

  • BehaviorRelay 是作为Variable 的替代者出现的。它的本质其实也是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
  • BehaviorRelay 具有 BehaviorSubject的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
  • 与 BehaviorSubject 不同的是,不需要也不能手动给 BehaviorReply 发送 completed 或者 error 事件来结束它(BehaviorRelay 会在销毁时也不会自动发送 .complete 的 event)。
    BehaviorRelay 有一个 value 属性,我们通过这个属性可以获取最新值。而通过它的 accept() 方法可以对值进行修改
let subject = BehaviorRelay<String>(value: "初始值")
        subject.accept("第一条消息")
        subject.asObservable().subscribe {
            print("第1次订阅:", $0)
        }.disposed(by: disposeBag)
        subject.accept("第二条消息")

        subject.asObservable().subscribe {
            print("第2次订阅:", $0)
        }.disposed(by: disposeBag)
        subject.accept("第三条消息")

https://www.jianshu.com/p/def6965b0475
https://blog.csdn.net/qq_30963589/article/details/112171117

相关文章

  • RxSwift4-Subjects介绍

    看了前面介绍的创建Observable的方式, 我们应该会想,在项目的实际使用中,大多数情况都是预先不知道序列值的...

  • Runtime介绍---术语介绍

    1. 什么是Runtime Runtime又叫运行时,是一套C语言的API。 我们平时编写的OC代码,底层都是基于...

  • 介绍

    万物终有一天会消失殆尽,诸神出卖黎明,光明为黑暗所湮灭,日月皆痕,海潮鸣泣,幼雏嚎啕,生灵涂炭。 托里奥世纪第20...

  • 介绍😊

    大家好,我是beth,初入简书,不邀自来,还请各位见谅! 先说说我是怎么想着来的吧?这不是刚过了一个寒假嘛...

  • 介绍

    在这个世界上还有三个家族他们不受各个国家联合国管。但他们身上有着使命分别是帝国家族曲国家族圣国家族。他们隐藏在一个...

  • 介绍

    云轩:主角,星罗帝国的二皇子。从小就不能练气,被人们称为废物。直到12岁的时候,自己的武魂觉醒才能练气,双...

  • 介绍

    万花阁 神秘至极的组织,亦正亦邪。万花阁的人行动隐秘,至今未被发现所在地。听说组成成员均以花来命名。所到之处,皆留...

  • 介绍

    此书命曰元.八洲传。属九洲四传第二部。第一部,上古往事。上古往事乃元八洲传外传。前两部为战胜心魔,而第三部,大梦...

  • 介绍

    千肆篇 7月的天气燥热,但在红杏阁里这份燥热就别有一番风味。漫天的胭脂水粉的香味变成了调味剂,女人们千姿百媚,在...

  • 介绍

    该文集属于收录文集,里面的内容不全是本人创作,有收录个人喜欢的内容。 *(偏个人向)

网友评论

    本文标题:RxSwift4-Subjects介绍

    本文链接:https://www.haomeiwen.com/subject/wrwdlltx.html