0 前言
第二節(jié)開頭的時候穩(wěn)定頂一個協(xié)議擴(kuò)展和一個方法庭砍,便于本章中方法的測試
協(xié)議擴(kuò)展是給每個觀察者加一個id的標(biāo)示符并且打印事件相關(guān)的信息
方法的大致作用是將觀察序列作為參數(shù)傳入舔示,然后訂閱此序列
extension ObservableType {
/**
Add observer with `id` and print each emitted event.
- parameter id: an identifier for the subscription.
*/
func addObserver(_ id: String) -> Disposable {
return subscribe { print("Subscription:", id, "Event:", $0) }
}
}
func writeSequenceToConsole<O: ObservableType>(name: String, sequence: O) -> Disposable {
return sequence.subscribe { event in
print("Subscription: \(name), event: \(event)")
}
}
接下來進(jìn)行本章的翻譯
Working with Subjects
- subject介紹
subject 在Rx的某些實現(xiàn)中充當(dāng)?shù)氖菢蛄夯虼砟⒅荆瘸洚?dāng)觀察者又充當(dāng)被觀察者。 因為它是一個觀察者假哎,它可以訂閱一個或多個觀察器擎浴,又因為是被觀察者虱疏,所以它可以通過重新發(fā)出它們觀察到的項目,并且它也可以發(fā)射新的項目魂拦。
-
PublishSubject
向所有的觀察者發(fā)送新事件毛仪,這些事件是觀察者訂閱之后的事件,訂閱之前的事件芯勘,觀察者無法接收到
example("PublishSubject") {
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject.addObserver("1").disposed(by: disposeBag)
subject.onNext("??")
subject.onNext("??")
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("???")
subject.onNext("???")
}
// 控制臺打印的結(jié)果:
--- PublishSubject example ---
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
其中onNext(:) 方法等同于on(.next(:)方法, 作用是為向訂閱者發(fā)送Next 事件
-
ReplaySubject
在新的訂閱者訂閱的時候會補發(fā)事件箱靴,bufferSize決定補發(fā)事件的數(shù)量,如果bufferSize為1則補發(fā)一個事件荷愕,為2則補發(fā)兩個
觀察一下bufferSize為1和2不同的值的時候控制臺打印的不同情況
example("ReplaySubject") {
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 1)
subject.addObserver("1").disposed(by: disposeBag)
subject.onNext("??")
subject.onNext("??")
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("???")
subject.onNext("???")
}
// bufferSize = 1
// 控制臺打印的結(jié)果:
--- ReplaySubject example ---
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
// bufferSize = 2
// 控制臺打印的結(jié)果:
--- ReplaySubject example ---
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
-
BehaviorSubject
向新的訂閱者補發(fā)送新的事件衡怀,如果沒有新事件就補發(fā)默認(rèn)值,默認(rèn)值應(yīng)該是在BehaviorSubject初始化時候創(chuàng)建的
example("BehaviorSubject") {
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "??")
subject.addObserver("1").disposed(by: disposeBag)
subject.onNext("??")
subject.onNext("??")
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("???")
subject.onNext("???")
subject.addObserver("3").disposed(by: disposeBag)
subject.onNext("??")
subject.onNext("??")
}
// 控制臺打印的結(jié)果:
--- BehaviorSubject example ---
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 3 Event: next(???)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 3 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 3 Event: next(??)
PublishSubject, ReplaySubject, and BehaviorSubject這三種的subject在
disposed of.
的時候不需要自動發(fā)出Complete 事件安疗,
-
Variable
Variable是對BehaviorSubject的封裝抛杨,所以它具向訂閱者發(fā)送最近的值的功能。它還有保存當(dāng)前的值得的功能荐类,它不會發(fā)出Error事件怖现,但是它會自動發(fā)送Complete事件,并在deinit的時候終止
example("Variable") {
let disposeBag = DisposeBag()
let variable = Variable("??")
variable.asObservable().addObserver("1").disposed(by: disposeBag)
variable.value = "??"
variable.value = "??"
variable.asObservable().addObserver("2").disposed(by: disposeBag)
variable.value = "???"
variable.value = "???"
}
// 控制臺打印的結(jié)果:
--- Variable example ---
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 1 Event: next(??)
Subscription: 2 Event: next(??)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: next(???)
Subscription: 2 Event: next(???)
Subscription: 1 Event: completed
Subscription: 2 Event: completed
** Variable 對象調(diào)用asObservable() 方法是為了訪問其底層的BehaviorSubject序列玉罐。 變量沒有使用on運算符(例如onNext(_ :))屈嗤,而是暴露可用于獲取當(dāng)前值的value屬性,并設(shè)置一個新值吊输。 設(shè)置一個新值也會將該值添加到其底層的BehaviorSubject序列中饶号。**
此處對Variable 和 BehaviorSubject 做一下對比 :
example("Variable") {
let disposeBag = DisposeBag()
let variable = Variable("??")
variable.asObservable().addObserver("1").disposed(by: disposeBag)
variable.value = "??"
variable.value = "??"
variable.asObservable().addObserver("2").disposed(by: disposeBag)
variable.value = "???"
variable.value = "???"
}
example("BehaviorSubject") {
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "??")
subject.addObserver("1").disposed(by: disposeBag)
subject.onNext("??")
subject.onNext("??")
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("???")
subject.onNext("???")
}
對比打印結(jié)果
可以看出Variable會自動發(fā)出Complete事件
對比結(jié)果