RxSwift Observable&Observer和

2018-09-22  本文已影响11人  darrenW

在我们日常开发中,有一些既可是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是将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者。

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。这样会导致无序调用,将造成意想不到的结果。

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事件发出来。

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

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
上一篇 下一篇

猜你喜欢

热点阅读