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介绍

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