zoukankan      html  css  js  c++  java
  • RxSwift学习笔记6:Subjects/PublishSubject/BehaviorSubject/ReplaySubject/Variable

         // 从前面的几篇文章可以发现,当我们创建一个 Observable 的时候就要预先将要发出的数据都准备好,等到有人订阅它时再将数据通过 Event 发出去。
            // 但有时我们希望 Observable 在运行时能动态地“获得”或者说“产生”出一个新的数据,再通过 Event 发送出去。
            //比如:订阅一个输入框的输入内容,当用户每输入一个字后,这个输入框关联的 Observable 就会发出一个带有输入内容的 Event,通知给所有订阅者。
            //这个就可以使用下面将要介绍的 Subjects 来实现。
            //
            //1,Subjects 基本介绍
            //(1)Subjects 既是订阅者,也是 Observable:
            //说它是订阅者,是因为它能够动态地接收新的值。
            //说它又是一个 Observable,是因为当 Subjects 有了新的值之后,就会通过 Event 将新值发出给他的所有订阅者。
            //
            //(2)一共有四种 Subjects,分别为:PublishSubject、BehaviorSubject、ReplaySubject、Variable。他们之间既有各自的特点,也有相同之处:
            //首先他们都是 Observable,他们的订阅者都能收到他们发出的新的 Event。
            //直到 Subject 发出 .complete 或者 .error 的 Event 后,该 Subject 便终结了,同时它也就不会再发出 .next 事件。
            //对于那些在 Subject 终结后再订阅他的订阅者,也能收到 subject 发出的一条 .complete 或 .error 的 event,告诉这个新的订阅者它已经终结了。
            //他们之间最大的区别只是在于:当一个新的订阅者刚订阅它的时候,能不能收到 Subject 以前发出过的旧 Event,如果能的话又能收到多少个。
            //
            //(3)Subject 常用的几个方法:
            //onNext(:):是 on(.next(:)) 的简便写法。该方法相当于 subject 接收到一个 .next 事件。
            //onError(:):是 on(.error(:)) 的简便写法。该方法相当于 subject 接收到一个 .error 事件。
            //onCompleted():是 on(.completed) 的简便写法。该方法相当于 subject 接收到一个 .completed 事件。
        
            
            /*
             PublishSubject 是最普通的 Subject,它不需要初始值就能创建。
             PublishSubject 的订阅者从他们开始订阅的时间点起,可以收到订阅后 Subject 发出的新 Event,而不会收到他们在订阅前已发出的 Event。
             */
            let publishSubject = PublishSubject<String>()
            publishSubject.onNext("111")
            
            publishSubject.subscribe(onNext: { (string) in
                print("第1次订阅:(string)")
            }, onError: { (error) in
                print(error.localizedDescription)
            }, onCompleted: {
                print("第1次订阅完成")
            }).disposed(by: disposeBag)
            
            publishSubject.onNext("222")
            
            publishSubject.subscribe(onNext: { (string) in
                print("第2次订阅:(string)")
            }, onError: { (error) in
                print(error.localizedDescription)
            }, onCompleted: {
                print("第2次订阅完成")
            }).disposed(by: disposeBag)
            
            publishSubject.onNext("333")
     
            publishSubject.onCompleted()
            
            publishSubject.onNext("444")
            
            publishSubject.subscribe(onNext: { (string) in
                print("第3次订阅:(string)")
            }, onError: { (error) in
                print(error.localizedDescription)
            }, onCompleted: {
                print("第3次订阅完成")
            }).disposed(by: disposeBag)
            print("==================================")
            /*
             第1次订阅:222
             第1次订阅:333
             第2次订阅:333
             第1次订阅完成
             第2次订阅完成
             第3次订阅完成
             */
            
            
            //BehaviorSubject
            //BehaviorSubject 需要通过一个默认初始值来创建。
            //当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个发出的 event。
            //之后就跟正常的情况一样,它也会接收到 BehaviorSubject 之后发出的新的 event。
            let behaviorSubject = BehaviorSubject(value: "111")
            behaviorSubject.subscribe { (event) in
                print("第1次订阅:(event)")
                }.disposed(by: disposeBag)
            
            behaviorSubject.onNext("222")
            
            behaviorSubject.onError(NSError(domain: "localErro", code: 0, userInfo: nil))
            behaviorSubject.subscribe { (event) in
                print("第2次订阅:(event)")
                }.disposed(by: disposeBag)
            print("==================================")
            /*
             第1次订阅:next(111)
             第1次订阅:next(222)
             第1次订阅:error(Error Domain=localErro Code=0 "(null)")
             第2次订阅:error(Error Domain=localErro Code=0 "(null)")
             */
            
            
            // ReplaySubject基本介绍 :
            // ReplaySubject 在创建时候需要设置一个 bufferSize,表示它对于它发送过的 event 的缓存个数。
            // 比如一个 ReplaySubject 的 bufferSize 设置为 2,它发出了 3 个 .next 的 event,那么它会将后两个(最近的两个)event 给缓存起来。
            // 此时如果有一个 subscriber 订阅了这个 ReplaySubject,那么这个 subscriber 就会立即收到前面缓存的两个 .next 的 event。
            // 如果一个 subscriber 订阅已经结束的 ReplaySubject,除了会收到缓存的 .next 的 event 外,还会收到那个终结的 .error 或者 .complete 的 event。
            
            let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
            replaySubject.onNext("111")
            replaySubject.onNext("222")
            replaySubject.onNext("333")
            replaySubject.onNext("444")
            
            replaySubject.subscribe { (event) in
                print("第1次订阅:(event)")
                }.disposed(by: disposeBag)
            
            replaySubject.onNext("555")
            replaySubject.subscribe { (event) in
                print("第2次订阅:(event)")
                }.disposed(by: disposeBag)
            
            replaySubject.onCompleted()
            
            replaySubject.subscribe { (event) in
                print("第3次订阅:(event)")
                }.disposed(by: disposeBag)
            print("==================================")
            /*
             第1次订阅:next(333)
             第1次订阅:next(444)
             第1次订阅:next(555)
             第2次订阅:next(444)
             第2次订阅:next(555)
             第1次订阅:completed
             第2次订阅:completed
             第3次订阅:next(444)
             第3次订阅:next(555)
             第3次订阅:completed
             */
            
            
            // BehaviorRelay 基本介绍
            // BehaviorRelay 是作为 Variable(Variable 在之后版本中将被废弃,建议使用 Varible 的地方都改用下面介绍的 BehaviorRelay 作为替代) 的替代者出现的。
            // 它的本质其实也是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
            // BehaviorRelay 具有 BehaviorSubject 的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
            // 与 BehaviorSubject 不同的是,BehaviorRelay 会在销毁时自动发送 .complete 的 event,不需要也不能手动给 BehaviorReply 发送 completed 或者 error 事件来结束它。
            // BehaviorRelay 有一个 value 属性,我们通过这个属性可以获取最新值。而通过它的 accept() 方法可以对值进行修改。
            
            let behaviorRelay = BehaviorRelay(value: "111")
            behaviorRelay.accept("222")
            behaviorRelay.asObservable().subscribe { (event) in
                print("第1次订阅:(event)")
            }.disposed(by: disposeBag)
            behaviorRelay.accept("333")
            
            behaviorRelay.asObservable().subscribe {
                print("第2次订阅:($0)")
                }.disposed(by: disposeBag)
            
            behaviorRelay.accept("444")
            print("==================================")
            /*
             第1次订阅:next(222)
             第1次订阅:next(333)
             第2次订阅:next(333)
             第1次订阅:next(444)
             第2次订阅:next(444)
             */
            
            //如果想将新值合并到原值上,可以通过 accept() 方法与 value 属性配合来实现。
            //这个常用在表格上拉加载功能上,BehaviorRelay 用来保存所有加载到的数据
            
            let behaviorRelay1 = BehaviorRelay<[String]>(value: ["1"])
            behaviorRelay1.accept(behaviorRelay1.value + ["2","3"])
            behaviorRelay1.asObservable().subscribe {
                print("第1次订阅:($0)")
                }.disposed(by: disposeBag)
            
            behaviorRelay1.accept(behaviorRelay1.value + ["4","5"])
            behaviorRelay1.asObservable().subscribe {
                print("第2次订阅:($0)")
                }.disposed(by: disposeBag)
            
            behaviorRelay1.accept(behaviorRelay1.value + ["6","7"])
            /*
             第1次订阅:next(["1", "2", "3"])
             第1次订阅:next(["1", "2", "3", "4", "5"])
             第2次订阅:next(["1", "2", "3", "4", "5"])
             第1次订阅:next(["1", "2", "3", "4", "5", "6", "7"])
             第2次订阅:next(["1", "2", "3", "4", "5", "6", "7"])
             */
    

      

  • 相关阅读:
    石子归并
    【性能测试工具】- ApacheBench
    如何提问
    HTTP 0.9 / 1.0 / 1.1
    【NO.3-1】Jmeter
    【有意思的BUG】未名
    【FlashPlayer】-Debug版本-开发人员推荐
    【NO.1】Jmeter-安装JDK- 配置Jmeter运行的环境
    【IP限制】验证是否限制了境外IP访问权限
    【有意思的BUG】视频连接超时
  • 原文地址:https://www.cnblogs.com/mapanguan/p/9257048.html
Copyright © 2011-2022 走看看