RxSwift 系列(二) -- Subject
前言
Subject是一个代理,它既是Observer,也是Observable。因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其他的Observer订阅。它可以传递/转发作为Observer收到的值,也可以主动发射值。
Subject在RxSwift中的实现有四种:
PublishSubjectReplaySubjectBehaviorSubjectVariable
PublishSubject
代理
我们先以PublishSubject为例来解释Subject是一个代理的含义。
let subject = PublishSubject<Int>()
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
Subject作为一个Observable提供了subscribe等方法。在订阅之后,我们调用了onNext(),向Observer发射了1、2,以及onCompleted()。打印结果和我们预期的是一样的。
Event:next(1)
Event:next(2)
Event:completed
我们可以调用Subject的on系列方法主动给Observer发送值。
Subject可以作为代理转发订阅到的结果。例如:
let subject = PublishSubject<Int>()
subject.subscribe({ (event) in
print("Event:\(event)")
})
let reveseSubject = Observable<Int>.create({ (observer) -> Disposable in
observer.onNext(1)
observer.onNext(2)
observer.onCompleted()
return Disposables.create()
})
reveseSubject.subscribe(subject)
subject订阅了reveseSubject,并将结果转发给了Observer。
注意:
Observer订阅subject时不会收到订阅之前subject的值。
let subject = PublishSubject<Int>()
subject.onNext(0)
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
上述代码结果为:
Event:next(1)
Event:next(2)
Event:completed
observer无法接收到0这个值。
ReplaySubject
ReplaySubject和PublishSubject不同的是,Observer有可能接收到订阅之前的值。
let subject = ReplaySubject<Int>.create(bufferSize: 1)
subject.onNext(0)
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
上述代码结果为:
Event:next(0)
Event:next(1)
Event:next(2)
Event:completed
ReplaySubject具有重放(replay)的功能,replay的个数可以通过参数指定。我们可以将其理解为缓存的效果。
一般我们使用ReplaySubject的时候,都是先发射,后订阅,然后通过指定缓存的大小,可以获取对应的值。(注意:不考虑Error和Completed)。
let subject = ReplaySubject<Int>.create(bufferSize: 1)
subject.onNext(0)
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
subject.subscribe({ (event) in
print("Event:\(event)")
})
上述代码,我们指定了bufferSize等于1,所以只缓存了最新的值,打印结果:
Event:next(2)
Event:completed
当我们需要缓存所有值的时候,可以调用createUnbounded()方法。
ReplaySubject.create(bufferSize: 0) 等同于 PublishSubject()。
BehaviorSubject
BehaviorSubject类似于ReplaySubject具有缓存能力,但是略有不同。
- 只缓存一个最新值,类似
ReplaySubject.create(bufferSize: 1) - 需要提供默认值
let behaviorSubject = BehaviorSubject<Int>(value: 1)
behaviorSubject.subscribe({ (event) in
print("Event:\(event)")
})
打印结果为:
Event:next(1)
使用BehaviorSubject有一点好处,我们可以确定当Observer订阅时,至少可以收到最新的一个值。
Variable
Variable和BehaviorSubject又很相似,Variable是BehaviorSubject的一个封装,同样具备了缓存最新值和提供默认值的能力。但是Variable没有on系列方法,只提供了value属性。
直接对value进行set等同于调用了onNext()方法。
这表明了Variable不会发射error也不会发射completed
在Variable被销毁的时候会调用发射completed给Observer
在订阅Variable的时候,我们无法直接调用subscribe方法,需要先调用asObservable()方法。
let variable = Variable<Int>(1)
variable.asObservable().subscribe({ (event) in
print("Event:\(event)")
})
variable.value = 2
上述结果为:
Event:next(1)
Event:next(2)
Event:completed
Variable可以用来储存数据,因为我们可以拥有value的get和set方法。比如:
let variable = Variable(1)
print("Value: \(variable.value)")
variable.value = 2
print("Value: \(variable.value)")
打印结果为:
Value: 1
Value: 2
这是BehaviorSubject不具备的。
RxSwift 系列(二) -- Subject的更多相关文章
- RxSwift 系列(二)
前言 Subject是一个代理,它既是Observer,也是Observable.因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其 ...
- sed修炼系列(二):sed武功心法(info sed翻译+注解)
sed系列文章: sed修炼系列(一):花拳绣腿之入门篇sed修炼系列(二):武功心法(info sed翻译+注解)sed修炼系列(三):sed高级应用之实现窗口滑动技术sed修炼系列(四):sed中 ...
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- 前端构建大法 Gulp 系列 (二):为什么选择gulp
系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...
- WPF入门教程系列二十三——DataGrid示例(三)
DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...
- Web 开发人员和设计师必读文章推荐【系列二十九】
<Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发人员和设计师必读文章推荐【系列二十八】
<Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】
<Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发人员和设计师必读精华文章【系列二十六】
<Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
随机推荐
- 奇妙的 CSS shapes(CSS图形)
CSS 发展到今天已经越来越强大了.其语法的日新月异,让很多以前完成不了的事情,现在可以非常轻松的做到.今天就向大家介绍几个比较新的强大的 CSS 功能: clip-path shape-outsid ...
- Shiro眼皮下玩ajax,玩出302 Found(实践得经验)
2017/06/14这一天,是我玩Shiro安全框架最刻骨铭心的一天.因为Shiro今天给我深深的补了一刀,在这儿我也给各位补一刀吧,其实问题很简单,解决方式也极其简单,只是给各位分享一下这个错误,纯 ...
- Redis数据类型之List(三)
前言:list即链表,它是一个能维持数据先后顺序的列表,便于在表的两端追加和删除数据,中间位置的存取具有O(N)的时间复杂度,是一个双向链表. 一.内部原理 redis ...
- Eclipse导出JavaDoc中文乱码问题解决
在Eclipse里 export 选 JavaDoc,在向导的最后一页的Extra JavaDoc Options 里填上参数即可 比如项目采用的是UTF-8的编码就填:-encoding UTF-8 ...
- schema 对象的简单介绍
官方文档链接地址 http://docs.oracle.com/cd/E11882_01/server.112/e40540/tablecls.htm#CNCPT010 Introduction to ...
- angular中的$q服务
$q的一共有四个api: 1.$q.when(value, successFn, errorFn, progressFn),返回值为一个promise对象 --value可以是一个任意数据,也可以是一 ...
- 持续集成篇-- SonarQube代码质量管理平台的配置与使用
样例视频教程:http://www.roncoo.com/course/view/85d6008fe77c4199b0cdd2885eaeee53 一.SonarQube的配置(前提,先用admin用 ...
- Swift区间运算符
Swift 提供了两个方便表达一个区间的值的运算符. 闭区间运算符 闭区间运算符(a...b)定义一个包含从a到b(包括a和b)的所有值的区间. 闭区间运算符在迭代一个区间的所有值时是非常有用的, ...
- 耍一把codegen,这样算懂编译么?
最近使用protobuf搭了些服务器,对protobuf的机制略感兴趣,所以研究了下. 大致分析没有什么复杂的 1 对定义的结构体生成消息封包协议 2 对定义的rpc函数生成接口定义 3 用户按pro ...
- 【Android Developers Training】 92. 序言:使用同步适配器传输数据
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...