// 从前面的几篇文章可以发现,当我们创建一个 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"])
*/

  

RxSwift学习笔记6:Subjects/PublishSubject/BehaviorSubject/ReplaySubject/Variable的更多相关文章

  1. RxSwift学习笔记7:buffer/window/map/flatMap/flatMapLatest/flatMapFirst/concatMap/scan/groupBy

    1.buffer的基本使用 let publishSubject = PublishSubject<String>() //buffer 方法作用是缓冲组合,第一个参数是缓冲时间,第二个参 ...

  2. RxSwift学习笔记之Subject

    本文为原创文章,转载请标明出处 AsyncSubject 一个AsyncSubject只在原始Observable完成后,发射来自原始Observable的最后一个值.它会把这最后一个值发射给任何后续 ...

  3. RxSwift学习笔记10:startWith/merge/zip/combineLatest/withLatestFrom/switchLatest

    //startWith //该方法会在 Observable 序列开始之前插入一些事件元素.即发出事件消息之前,会先发出这些预先插入的事件消息 Observable.of(1,2,3) .startW ...

  4. RxSwift学习笔记9:amb/tabkeWhile/tabkeUntil/skipWhile/skipUntil

    //amb基本介绍 //当传入多个 Observables 到 amb 操作符时,它将取第一个发出元素或产生事件的 Observable,然后只发出它的元素. //并忽略掉其他的 Observable ...

  5. RxSwift学习笔记8:filter/distinctUntilChanged/single/elementAt/ignoreElements/take/takeLast/skip/sample/debounce

    //filter:该操作符就是用来过滤掉某些不符合要求的事件. Observable.of(1,2,3,4,5,8).filter({ $0 % 2 == 0 }).subscribe { (even ...

  6. RxSwift学习笔记5:Binder

    使用 Binder 创建观察者 //Observable序列(每隔1秒钟发出一个索引数) let scheduleObservable = Observable<Int>.interval ...

  7. RxSwift学习笔记2:Observable/生命周期/Event/oneNext/onError/onCompleted/

     Observable 是 Rx 的根基 官网:http://reactivex.io/ github地址:https://github.com/ReactiveX/RxSwift Observabl ...

  8. RxSwift学习笔记1:RxSwift的编程风格

    第一天:简单体验与RxSwift的编程风格 import UIKit//导入Rx相关框架 import RxSwift import RxCocoa struct Music { let name:S ...

  9. RxSwift学习笔记4:disposeBag/scheduler/AnyObserver/Binder

    let disposeBg = DisposeBag() //直接在创建 //在 subscribe 方法中创建 let ofObserval = Observable.of("a" ...

随机推荐

  1. centos7 下安装mongodb指南;

    1.下载:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.1.tgz; 2.解压缩; 3.文件存储在mongodb文件 ...

  2. C++动态链接库

    1.动态链接库概述: 动态链接库通常都不能直接运行,也不能接受消息:只有在其他模块调用动态链接库中的函数时,它才发挥作用. Windows API中所有的函数都包含在动态链接库中. 动态链接库分静态库 ...

  3. ps教程分享:一定要记住这20种PS技术!

    一定要记住这20种PS技术!会让你的照片美的不行! 一种简单的数码照片后期润饰 1)打开图片,执行色像/饱和度(-40)降低饱和度. 2)新建一图层,将图层模式改为柔光,用画笔工具将需要润饰的部分画几 ...

  4. tomcat+servlet例子

    在C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\app\WEB-INF文件夹下建立文件夹classes. 在C:\Pro ...

  5. Redis学习笔记:windows上redis的安装运行

    Redis的windows版本地址https://github.com/MicrosoftArchive/redis 下载之后解压之 在当前解压目录下可以看到如下文件 在当前目录下打开命令行窗口,输入 ...

  6. OneZero_Aphla发布总结以及自己的体会

    Aphla发布正式结束了.清明时节,总要祭奠点什么. 以下是这一周的燃尽图. 可以发现,并没有燃尽.所以OneZero的Aphla发布失败了. 失败原因有至少以下三点: 1.组长分配任务存在隐患,高风 ...

  7. linux系统,在centos7环境下安装jdk步骤

    记录一下安装jdk1.8版本的出错过程: 按照这个博客内容安装的,以及修改文件权限博客 [Linux]CentOS7下安装JDK详细过程 [Linux]目录文件权限的查看和修改[转] 1.安装的jdk ...

  8. 斐波那契数列(NOIP1997)

    题目链接:斐波那契数列 这题是数论的一个基本应用,还是很水,因为数据范围太水了,只有48,这也太小了.不过也有可能是当时的电脑速度跑得比较慢的原因.但是这个算法应该还是这个算法.主要思路就是递推求斐波 ...

  9. 数组方法concat & slice

    掌握数组的操作方法: concat() /  slice() concat() 语法: arrayObject.concat(arrayX,arrayY,....,arrayZ) 功能:用于连接两个或 ...

  10. AttributeError: type object 'testClass' has no attribute 'testMothod'

    点击"Unittest for test_post_API.testClass"按钮,点击”Edit configuration...“,弹出对话框Run/Debug config ...