RxSwift学习-基础概念(译二)
Working with Subjects
A Subject is a sort of bridge or proxy that is available in some implementations of Rx that acts as both an observer and Observable. Because it is an observer, it can subscribe to one or more Observables, and because it is an Observable, it can pass through the items it observes by reemitting them, and it can also emit new items.
Subjet是observable和Observer之间的桥梁,一个Subject既是一个Obserable也是一个Observer,他既可以发出事件,也可以监听事件
(1)PublishSubject
Broadcasts new events to all observers as of their time of the subscription.
广播新的事件给所有观察者,订阅他之后才能接收到事件
example("PublishSubject") {
llet subject = PublishSubject<String>()
_ = subject.subscribe({ (sender:Event) in
print(sender)
})
subject.onNext("1")
_ = subject.subscribe(onNext: { (element) in
print("订阅者一:" + element)
})
subject.on(.next("2"))
_ = subject.subscribe(onNext: { (element) in
print("订阅者二:" + element)
})
subject.onNext("3")
}
本例子使用onNext方法,这个方法将导致信的事件发送给订阅者,其中包好所提供的元素。
(2)ReplaySubject
Broadcasts new events to all subscribers, and the specified bufferSize number of previous events to new subscribers.
向所有订阅者广播 新事件,以及向新的订阅者 广播 指定大小的旧的事件。
当你订阅ReplaySubject的时候,你可以接收到订阅他之后的事件,但也可以接受订阅他之前发出的事件,接受几个事件取决与bufferSize的大小
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 1)
let subject = ReplaySubject<String>.create(bufferSize: 1)
subject.onNext(" Rxj")
subject.onNext("🐶")
subject.subscribe { (sender:Event) in
print(sender)
}.addDisposableTo(disposeBag)
subject.onNext("🐱")
next(🐶) //订阅之前还可以接收一次前面的最后一个事件,Rxj不会被接收
next(🐱)
(3)BehaviorSubject
Broadcasts new events to all subscribers, and the most recent (or initial) value to new subscribers.
广播新的事件给所有订阅者, 新的订阅者可以接收到你订阅者之前的最后一个事件
example("Variable") {
let disposeBag = DisposeBag()
subject.subscribe({ (event) in
print(label: "订阅者一:", event: event)
})
.disposed(by: disposeBag)
subject.onNext("2")
subject.onError(MyError.anError)
subject.subscribe({ (event) in
print(label: "订阅者二:", event: event)
})
.disposed(by: disposeBag)
}
Notice what's missing in these previous examples? A Completed event. PublishSubject, ReplaySubject, and BehaviorSubject do not automatically emit Completed events when they are about to be disposed of.
注意:PublishSubject, ReplaySubject和BehaviorSubject是不会自动发出completed事件的。
(4)Variable
Wraps a BehaviorSubject, so it will emit the most recent (or initial) value to new subscribers. And Variable also maintains current value state. Variable will never emit an Error event. However, it will automatically emit a Completed event and terminate on deinit.
behaviorsubject的包装箱,它会发送订阅之前最后一个事件给新的订阅者,Variable发送的事件也同样包含了当前的事件。
Variable永远不会发出错误事件,然而它会自动发出一个已完成的事件,在deinit的事件终止
let disposeBag = DisposeBag()
let variable = Variable("🔴")
variable.value = "0"
variable.value = "1"
variable.asObservable().subscribe({ (event) in
print("订阅者一:\(event)")
})
.disposed(by: disposeBag)
variable.value = "2"
variable.value = "3"
订阅者一:next(1)
订阅者一:next(2)
订阅者一:next(3)
订阅者一:completed
Call asObservable() on a Variable instance in order to access its underlying BehaviorSubject sequence. Variables do not implement the on operator (or, e.g., onNext(_:)), but instead expose a value property that can be used to get the current value, and also set a new value. Setting a new value will also add that value onto its underlying BehaviorSubject sequence.
在一个Variable 实例上添加 一个asObservable(),是为了访问潜在的 BehaviorSubject 序列.
Variable 没有提供onNext操作,但是代替提供了一个value属性,这个属性可以用来获取当前的value,也可以用来设置新的value。当设置新的value的时候会被添加到潜在的 BehaviorSubject 序列当中
联合操作
联合操作就是把多个Observable流合成单个Observable流
(5)startWith
Emits the specified sequence of elements before beginning to emit the elements from the source Observable.
在source ObserVable 发出新事件之前,先发送指定的元素序列。
比如发出事件2 ,3然后我startWith(1),那么就会先发出1,然后2 ,3.
let disposeBag = DisposeBag()
Observable.of("2", "3")
.startWith("1")
.subscribe(onNext: { print($0) })
.addDisposableTo(disposeBag)
As this example demonstrates, startWith can be chained on a last-in-first-out basis, i.e., each successive startWith's elements will be prepended before the prior startWith's elements.
这个例子中演示了,startWith 遵循 last-in-first-out (后进先出的原则) 。每一个后进去的startWith元素,将提到上一个Startwith元素之前
(6)merge
Combines elements from source Observable sequences into a single new Observable sequence, and will emit each element as it is emitted by each source Observable sequence.
将多个Observable序列 合并 成单个Observable序列,根据时间轴发出对应的事件
let disposeBag = DisposeBag()
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
Observable.of(subject1, subject2)
.merge()
.subscribe(onNext: { print($0) })
.addDisposableTo(disposeBag)
subject1.onNext("🅰️")
subject1.onNext("🅱️")
subject2.onNext("①")
subject2.onNext("②")
subject1.onNext("🆎")
subject2.onNext("③")
(7)zip
Combines up to 8 source Observable sequences into a single new Observable sequence, and will emit from the combined Observable sequence the elements from each of the source Observable sequences at the corresponding index.
绑定最多不超过8个的Observable序列,合并成一个Observable序列。
Zip是 按照index索引,一个序列的index元素 对应 另一个蓄力的index元素。没有对应的index元素,将不会被输出,如下面例子
let disposeBag = DisposeBag()
let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()
Observable.zip(stringSubject, intSubject) { stringElement, intElement in
"\(stringElement) \(intElement)"
}
.subscribe(onNext: { print($0) })
.addDisposableTo(disposeBag)
stringSubject.onNext("🅰️")
stringSubject.onNext("🅱️")
stringSubject.onNext("🆎")
intSubject.onNext(1)
intSubject.onNext(2)
🅰️ 1 将stringSubject和intSubject压缩到一起共同处理
🅱️ 2
//🆎 没有输出
(8)combineLatest
Combines up to 8 source Observable sequences into a single new Observable sequence, and will begin emitting from the combined Observable sequence the latest elements of each source Observable sequence once all source sequences have emitted at least one element, and also when any of the source Observable sequences emits a new element
绑定超过最多不超过8个的Observable流,结合在一起处理。
和Zip不同的是,如果一个序列的事件有更新,combineLatest将绑定两个序例的最新事件。
看下面例子输出结果,你将一目了然
let disposeBag = DisposeBag()
let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()
Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in
"\(stringElement) \(intElement)"
}
.subscribe(onNext: { print($0) })
.addDisposableTo(disposeBag)
stringSubject.onNext("🅰️")
stringSubject.onNext("🅱️")
intSubject.onNext(1)
stringSubject.onNext("🆎")
intSubject.onNext(2)
🅱️ 1
🆎 1
🆎 2
There is also a variant of combineLatest that takes an Array (or any other collection of Observable sequences):
当观察序列是一个数组或者其他集合的时候
example("Array.combineLatest") {
let disposeBag = DisposeBag()
let stringObservable = Observable.just("❤️")
let fruitObservable = Observable.from(["🍎", "🍐", "🍊"])
let animalObservable = Observable.of("🐶", "🐱", "🐭", "🐹")
Observable.combineLatest([stringObservable, fruitObservable, animalObservable]) {
"\($0[0]) \($0[1]) \($0[2])"
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
}
对于打印结果是怎么去组合的,目前我还是蒙蔽的,这里要求每一个可观察序列要同一个类型
(9)switchLatest
ransforms the elements emitted by an Observable sequence into Observable sequences, and emits elements from the most recent inner Observable sequence
switchLatest可以对事件流进行转换,本来监听的subject1,我可以通过更改variable里面的value更换事件源。变成监听subject2了
let disposeBag = DisposeBag()
let subject1 = BehaviorSubject(value: "⚽️")
let subject2 = BehaviorSubject(value: "🍎")
let variable = Variable(subject1)
variable.asObservable()
.switchLatest()
.subscribe(onNext: { print($0) })
.addDisposableTo(disposeBag)
let subject1 = BehaviorSubject(value: "⚽️")
let subject2 = BehaviorSubject(value: "🍎")
let variable = Variable(subject1)
variable.asObservable()
.switchLatest()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("🏈")
subject1.onNext("🏀")
subject2.onNext("Rxj")
variable.value = subject2
subject1.onNext("xxx")
subject1.onNext("ooo")
subject2.onNext("🍐")
variable.value = subject1
subject1.onNext("Rxj")
⚽️
🏈
🏀
Rxj
🍐
ooo
Raj
例子也演示了 BehaviorSubject 可以接收到订阅前的最后一个事件