当我们需要创建一个 Observable的时候,要预先将要发送的信号或数据准备好,等到有subscribe时再将数据通过 onXX发出去。
但是,当需要Observable 在运行时能动态地获取一个新的数据时候,再通过onXX发送给订阅者,以实现“联动”的效果。我们就要用到了Subject。
Subject介绍
SubjectSubject是一个代理,它是特殊的序列,既是Observer,同时又是Observable
Subject分为:PublishSubject、BehaviorSubject、ReplaySubject、AsyncSubject、BehaviorRelay
PublishSubject
-PublishSubject的创建需要定义类型,但不需要初始值。
-PublishSubject的订阅序列只能接收到subscribe之后的onXX事件,不能接收到subscribe之前的onXX事件。
// 1:初始化序列
let publishSub = PublishSubject<Int>()
//初始化一个PublishSubject 装着Int类型的序列
// 2:发送响应序列
publishSub.onNext(1)
// 3:订阅序列
publishSub.subscribe { print("订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送响应
publishSub.onNext(2)
publishSub.onNext(3)
订阅到了: next(2)
订阅到了: next(3)
BehaviorSubject
-BehaviorSubject 需要的创建需要给定一个初始的默认值,第一次subscribe之前如果没有发送onXX事件,那么订阅到的就是这个初始的默认值。如果第一次subscribe之前发送了onXX事件,那么会把初始值覆盖掉。
-如果subscribe之前发送多个onXX事件,只会保留临近的一个; subscribe之后发送的onXX事件都会执行
// 1:创建序列
let behaviorSub = BehaviorSubject.init(value: 100)
// 2:发送信号
behaviorSub.onNext(1)
behaviorSub.onNext(2)
// 3:订阅序列
behaviorSub.subscribe{ print("第一次订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送
behaviorSub.onNext(3)
behaviorSub.onNext(4)
// 再次订阅
behaviorSub.subscribe{ print("第二次订阅到了:",$0)}
.disposed(by: disposbag)
第一次订阅到了: next(2)
第一次订阅到了: next(3)
第一次订阅到了: next(4)
第二次订阅到了: next(4)
ReplaySubject
如果初始化设置bufferSize,那么连续发送信号,而subscribe能够订阅到的最大数量为bufferSize
设置bufferSize
// 1:创建序列
let replaySub = ReplaySubject<Int>.create(bufferSize: 2)
// 2:发送信号
replaySub.onNext(1)
replaySub.onNext(2)
replaySub.onNext(3)
replaySub.onNext(4)
// 3:订阅序列
replaySub.subscribe{ print("订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送
replaySub.onNext(7)
replaySub.onNext(8)
replaySub.onNext(9)
订阅到了: next(3)
订阅到了: next(4)
订阅到了: next(7)
订阅到了: next(8)
订阅到了: next(9)
createUnbounded,不设置bufferSize
// 1:创建序列
let replaySub = ReplaySubject<Int>.createUnbounded()
// 2:发送信号
replaySub.onNext(1)
replaySub.onNext(2)
replaySub.onNext(3)
replaySub.onNext(4)
// 3:订阅序列
replaySub.subscribe{ print("订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送
replaySub.onNext(7)
replaySub.onNext(8)
replaySub.onNext(9)
订阅到了: next(1)
订阅到了: next(2)
订阅到了: next(3)
订阅到了: next(4)
订阅到了: next(7)
订阅到了: next(8)
订阅到了: next(9)
AsyncSubject
遇到onError的话,onError之前的onXX发送全部作废
// 1:创建序列
let asynSub = AsyncSubject<Int>.init()
// 2:发送信号
asynSub.onNext(1)
asynSub.onNext(2)
// 3:订阅序列
asynSub.subscribe{ print("订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送
asynSub.onNext(3)
asynSub.onNext(4)
asynSub.onError(NSError.init(domain: "EpisodeError", code: 10086, userInfo: nil))
asynSub.onCompleted()
订阅到了: error(Error Domain=EpisodeError Code=10086 "(null)")
BehaviorRelay
BehaviorRelay替代Variable, 无需手写 on(event)事件,只需给属性赋值即可获取事件响应。
// 1:创建序列
let behaviorRelay = BehaviorRelay(value: 1)
// 3:订阅序列
behaviorRelay.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposbag)
print("accept前:\(behaviorRelay.value)")
// 2:发送信号
behaviorRelay.accept(100)
print("accept后:\(behaviorRelay.value)")
1
accept前:1
100
accept后:100
订阅到了: completed