RxSwift 系列(二) -- Subject

前言

Subject是一个代理,它既是Observer,也是Observable。因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其他的Observer订阅。它可以传递/转发作为Observer收到的值,也可以主动发射值。

SubjectRxSwift中的实现有四种:

  • PublishSubject
  • ReplaySubject
  • BehaviorSubject
  • Variable

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发射了12,以及onCompleted()。打印结果和我们预期的是一样的。

Event:next(1)
Event:next(2)
Event:completed

我们可以调用Subjecton系列方法主动给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

ReplaySubjectPublishSubject不同的是,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

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

VariableBehaviorSubject又很相似,VariableBehaviorSubject的一个封装,同样具备了缓存最新值和提供默认值的能力。但是Variable没有on系列方法,只提供了value属性。 直接对value进行set等同于调用了onNext()方法。

这表明了Variable不会发射error也不会发射completed

Variable被销毁的时候会调用发射completedObserver

在订阅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可以用来储存数据,因为我们可以拥有valuegetset方法。比如:

let variable = Variable(1)
print("Value: \(variable.value)")
variable.value = 2
print("Value: \(variable.value)")

打印结果为:

Value: 1
Value: 2

这是BehaviorSubject不具备的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏会跳舞的机器人

记一次系统密码安全事故以及修改方案

运营人员反馈在晚上十一点多收到系统后台登录的短信验证码,第二天在后台的操作日志中发现自已的账号有被登录过后台系统,但实际上自已并没有登录操作,怀疑账号被他人恶意...

1582
来自专栏老马寒门IT

JS 的加密库简介

作为前端,数据提交到后台之前,重要的数据要进行加密一下,虽然已经有 https 等技术,但是增加一道前端的加密还是相对更安全的。虽然,前端的加密很容破解,但是有...

3670
来自专栏PHP在线

JSON Web Token - 在Web应用间安全地传递信息

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。 让我们来假想一下一个场景。在A用户...

3786
来自专栏程序猿DD

JSON Web Token - 在Web应用间安全地传递信息

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

922
来自专栏Python小屋

使用Python编写自己的个人密码管理器

只需要记住一个加解密密钥即可,对于各平台的密码,使用密钥加密后存储到数据库,查询时使用同一个密钥进行解密。

1553
来自专栏信安之路

记一次详细的勒索病毒分析

第一次写病毒分析的文章,之前表哥丢给我一个样本断断续续分析了好几天才搞明白,如有任何错误,还请各位多加指点

1030
来自专栏编程

Nginx双证书ECC/RSA配置

大家好,我是你们的老朋友Alex。今天教大家使用nginx配置证书,双证书! Nginx1.11.0版本后提供了ESA/ECC双证书的支持,以下是参考链接: h...

7178
来自专栏实战docker

体验RxJava和lambda

RxJava是 ReactiveX在 Java上的开源的实现,简单概括,它就是一个实现异步操作的库,使用时最直观的感受就是在使用一个观察者模式的框架来完成我们的...

2816
来自专栏北京马哥教育

SSL/TLS原理详解

本文大部分整理自网络,相关文章请见文后参考。 SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰。...

1.7K13
来自专栏比原链

剥开比原看代码04:如何连上一个比原

Gitee地址:https://gitee.com/BytomBlockchain/bytom

771

扫码关注云+社区

领取腾讯云代金券