美文网首页
RxSwift Observable&Observer和

RxSwift Observable&Observer和

作者: darrenW | 来源:发表于2018-09-22 23:45 被阅读11次

在我们日常开发中,有一些既可是Observable又可是Observer。举个🌰:

let observable = textField.rx.text
observable.subscribe(onNext: { text in show(text: text) })

在这行代码中,textField当前文本就是一个Observable,当用户在textField中输入时,就会show文本内容。
再举个🌰:

let disposeBag = DisposeBag()
let observer = textField.rx.text
let observable = Observable<String>.just("A")
observable.bind(to: observer)
          .disposed(by: disposeBag)

这个时候,屏幕上就会显示:

textField.png
这时,textField的当前文本就是Observer
此外,框架中还有一些辅助类型,既可是Observable又可是Observer

1. AsyncSubject

AsyncSubject将在Observable产生完成事件后,发出最后一个元素(仅仅只有最后一个元素)。如果Observable没有发出任何元素,只有一个完成事件,那AsyncSubject也只有一个完成事件。如果Observableerror中止,那么AsyncSubject只会将error发送出来,不会发出其它元素。
举个🌰:

let disposeBag = DisposeBag()
//创建一个AsyncSubject
let subject = AsyncSubject<String>()
//订阅subject
subject.subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
subject.onCompleted()

这个时候输出:

next(D)
completed

此时我们再改造一下:

let subject = AsyncSubject<String>()
subject.subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.onNext("D")
//SubjectError 自己定义的enum Error
subject.onError(SubjectError.error)

就会输出:

error(error)

2. PublishSubject

PublishSubject是将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者。

  • PublishSubject是最普通的Subject,它不需要初始值就能创建
  • PublishSubject的订阅者从他们开始订阅的时间点起,可以收到订阅后Subject发出的新Event,而不会收到他们在订阅前已发出的Event
    举个🌰:
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
//由于当前没有订阅,所以不输出
subject.onNext("🐶")
//第一次订阅
subject.subscribe(onNext: { (element) in
    print("第一次订阅:\(element)")
}, onCompleted: {
    print("completed")
}).disposed(by: disposeBag)
//当前有一个订阅,输出
subject.onNext("🐱")

//第二次订阅
subject.subscribe(onNext: { (element) in
    print("第二次订阅:\(element)")
}, onCompleted: {
    print("completed")
}).disposed(by: disposeBag)
//当前有两个订阅 输出
subject.onNext("🐹")

//结束subject
subject.onCompleted()
//再次发出.next事件
subject.onNext("🐯")

显示如下:

第一次订阅:🐱
第一次订阅:🐹
第二次订阅:🐹
第一次订阅:completed
第二次订阅:completed
第三次订阅:completed

3. ReplaySubject

ReplaySubject将对观察者发送全部的元素,无论观察者是何时进行订阅的。这里存在多个版本的ReplaySubject,有的只会将最新的n个元素发送给观察者,有的只会将限制时间段内最新的元素发送给观察者。如果把ReplaySubject当作观察者来使用,注意不要在多个线程调用onNext,onErroronCompleted。这样会导致无序调用,将造成意想不到的结果。

  • ReplaySubject在创建时候需要设置一个bufferSize,表示它对于它发送过的event的缓存个数
  • 比如一个ReplaySubjectbufferSize设置为 2,它发出了 3 个.nextevent,那么它会将后两个(最近的两个)event给缓存起来。此时如果有一个subscriber订阅了这个 ReplaySubject,那么这个subscriber就会立即收到前面缓存的两个.nextevent
  • 如果一个subscriber订阅已经结束的ReplaySubject,除了会收到缓存的.nextevent外,还会收到那个终结的.error或者.completeevent
    举个🌰:
let disposeBag = DisposeBag()
//创建
let subject = ReplaySubject<String>.create(bufferSize: 0)
//第1次订阅subject
subject.subscribe{ print("第一次订阅:\($0)") }
    .disposed(by: disposeBag)
//发送.next事件
subject.onNext("A")
subject.onNext("B")
//第二次订阅
subject.subscribe{ print("第二次订阅:\($0)" )}
    .disposed(by: disposeBag)
//发送.next事件
subject.onNext("C")
subject.onNext("D")

输出结果:

第一次订阅:next(A)
第一次订阅:next(B)
第一次订阅:next(C)
第二次订阅:next(C)
第一次订阅:next(D)
第二次订阅:next(D)

bufferSize改成1时,结果就变成了:

第一次订阅:next(A)
第一次订阅:next(B)
第二次订阅:next(B)
第一次订阅:next(C)
第二次订阅:next(C)
第一次订阅:next(D)
第二次订阅:next(D)

如果是2的话,结果就变成了:

第一次订阅:next(A)
第一次订阅:next(B)
第二次订阅:next(A)
第二次订阅:next(B)
第一次订阅:next(C)
第二次订阅:next(C)
第一次订阅:next(D)
第二次订阅:next(D)

4. BehaviorSubject

BehaviorSubject会把Observable最新元素发出来(如果不存在最新的元素,就发出默认元素)。然后将随后产生的元素发送出来。如果Observable因为error事件而中止,则不会发出任何元素,将error事件发出来。

  • BehaviorSubject需要通过一个默认初始值来创建
  • 当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects上一个发出的event。之后就跟正常的情况一样,它也会接收到BehaviorSubject之后发出的新的event
    举个🌰:
let disposeBag = DisposeBag()
//创建一个BehaviorSubject
let subject = BehaviorSubject.init(value: "🐭")
//第一次订阅
subject.subscribe{ print("第一次订阅:\($0)") }
        .disposed(by: disposeBag)
//发送.next事件
subject.onNext("🐯")
//发送error事件
subject.onError(NSError(domain: "local", code: 0, userInfo: nil))
//第二次订阅
subject.subscribe{ print("第二次订阅:\($0)") }
        .disposed(by: disposeBag)

输出结果:

第一次订阅:next(🐭)
第一次订阅:next(🐯)
第一次订阅:error(Error Domain=local Code=0 "(null)")
第二次订阅:error(Error Domain=local Code=0 "(null)")

4. Variable

RxSwift中,Variable相当于Swift中的var

  • Variable其实就是对BehaviorSubject的封装,所以它也必须要通过一个默认的初始值进行创建。
  • Variable具有BehaviorSubject的功能,能够向它的订阅者发出上一个event以及之后新创建的event
  • 不同的是,Variable还会把当前发出的值保存为自己的状态。同时它会在销毁时自动发送.completeevent,不需要也不能手动给Variables发送completed或者error事件来结束它。
  • 简单地说就是Variable有一个value属性,我们改变这个value属性的值就相当于调用一般SubjectsonNext()方法,而这个最新的onNext()的值就被保存在value属性里了,直到我们再次修改它。
  • Variables本身没有subscribe()方法,但是所有Subjects都有一个asObservable()方法。我们可以使用这个方法返回这个VariableObservable类型,拿到这个Observable类型我们就能订阅它了。
    举个🌰:
let disposeBag = DisposeBag()
let variable = Variable.init("A")
variable.value = "B"
//第一次订阅
variable.asObservable().subscribe{ print("第一次订阅:\($0)") }
    .disposed(by: disposeBag)
//修改value
variable.value = "C"
//第二次订阅
variable.asObservable().subscribe{ print("第二次订阅:\($0)") }
    .disposed(by: disposeBag)
//修改value
variable.value = "D"

结果如下:

第一次订阅:next(B)
第一次订阅:next(C)
第二次订阅:next(C)
第一次订阅:next(D)
第二次订阅:next(D)
第一次订阅:completed
第二次订阅:completed

相关文章

网友评论

      本文标题:RxSwift Observable&Observer和

      本文链接:https://www.haomeiwen.com/subject/budxoftx.html