一个Subject
是一种桥接或者是一种代理,在Rx中不仅可以当作观察者也可以当作可观察者来实现。由于她是一个观察者,可以订阅一个或者更多的可观察者,由于是一个可观察者,可以传递所观察的元素,也可以发出新的元素。
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)")
}
}
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("🅱️")
Tip : onNext就是响应式编程的响,observer就是应。代码走到noNext的地方的时候就会打印出
Subscription: 1 Event: next(🐶)
ReplaySubject
给所有的订阅者发送广播,并给特定的bufferSize
大小的之前的事件也给新的订阅者发一遍。
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) //这边也会打印一遍之前第一个事件 "🐶" 不过订阅者是2了
subject.onNext("🅰️")
subject.onNext("🅱️")
BehaviorSubject
给所有的订阅者发送新的事件,把最近的一个事件发给新来的订阅者
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "🔴")
subject.addObserver("1").disposed(by: disposeBag) //会把前面🔴事件也给1发一次
subject.onNext("🐶")
subject.onNext("🐱")
subject.addObserver("2").disposed(by: disposeBag) //会把前面🐱事件也给2发一次
subject.onNext("🅰️")
subject.onNext("🅱️")
subject.addObserver("3").disposed(by: disposeBag)
subject.onNext("🍐")
subject.onNext("🍊")
Variable
封装一下BehaviorSubject
,这样就会把最近的值发给新的订阅者。并且Variable
也可以保留当前值状态。Variable
不会发出错误事件,当然她会自动发出完成事件,并在deinit
终止。
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 = "🅱️"