美文网首页
可被监听的序列也是观察者

可被监听的序列也是观察者

作者: Satelens | 来源:发表于2018-12-20 21:44 被阅读14次

    AsyncSubject

    image.png

    AsyncSubject 将在源 Observable 产生完成事件后,发出最后一个元素(仅仅只有最后一个元素),如果源 Observable 没有发出任何元素,只有一个完成事件。那 AsyncSubject 也只有一个完成事件。

    image.png

    它会对随后的观察者发出最终元素。如果源 Observable 因为产生了一个 error 事件而中止, AsyncSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

    演示:

    let disposeBag = DisposeBag()
    let subject = AsyncSubject<String>()
    
    subject
      .subscribe { print("Subscription: 1 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🐶")
    subject.onNext("🐱")
    subject.onNext("🐹")
    subject.onCompleted()
    

    输出:

    Subscription: 1 Event: next(🐹)
    Subscription: 1 Event: completed
    

    PublishSubject

    image.png

    PublishSubject 将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者。如果你希望观察者接收到所有的元素,你可以通过使用 Observable 的 create 方法来创建 Observable,或者使用 ReplaySubject。

    image.png

    如果源 Observable 因为产生了一个 error 事件而中止, PublishSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

    演示:

    let disposeBag = DisposeBag()
    let subject = PublishSubject<String>()
    
    subject
      .subscribe { print("Subscription: 1 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject
      .subscribe { print("Subscription: 2 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🅰️")
    subject.onNext("🅱️")
    

    结果:

    Subscription: 1 Event: next(🐶)
    Subscription: 1 Event: next(🐱)
    Subscription: 1 Event: next(🅰️)
    Subscription: 2 Event: next(🅰️)
    Subscription: 1 Event: next(🅱️)
    Subscription: 2 Event: next(🅱️)
    

    ReplaySubject

    image.png

    ReplaySubject 将对观察者发送全部的元素,无论观察者是何时进行订阅的。

    这里存在多个版本的 ReplaySubject,有的只会将最新的 n 个元素发送给观察者,有的只会将限制时间段内最新的元素发送给观察者。

    如果把 ReplaySubject 当作观察者来使用,注意不要在多个线程调用 onNext, onError 或 onCompleted。这样会导致无序调用,将造成意想不到的结果。

    演示:

    let disposeBag = DisposeBag()
    let subject = ReplaySubject<String>.create(bufferSize: 1)
    
    subject
      .subscribe { print("Subscription: 1 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject
      .subscribe { print("Subscription: 2 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🅰️")
    subject.onNext("🅱️")
    

    结果:

    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(🅱️)
    

    BehaviorSubject

    image.png

    当观察者对 BehaviorSubject 进行订阅时,它会将源 Observable 中最新的元素发送出来(如果不存在最新的元素,就发出默认元素)。然后将随后产生的元素发送出来。

    image.png

    如果源 Observable 因为产生了一个 error 事件而中止, BehaviorSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

    演示:

    let disposeBag = DisposeBag()
    let subject = BehaviorSubject(value: "🔴")
    
    subject
      .subscribe { print("Subscription: 1 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject
      .subscribe { print("Subscription: 2 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🅰️")
    subject.onNext("🅱️")
    
    subject
      .subscribe { print("Subscription: 3 Event:", $0) }
      .disposed(by: disposeBag)
    
    subject.onNext("🍐")
    subject.onNext("🍊")
    

    结果:

    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(🍊)
    

    Variable

    通常使用var:

    // 在 ViewController 中
    var model: Model? = nil {
        didSet { updateUI(with: model) }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        model = getModel()
    }
    
    func updateUI(with model: Model?) { ... }
    func getModel() -> Model { ... }
    

    使用Variable:

    // 在 ViewController 中
    let model: Variable<Model?> = Variable(nil)
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        model.asObservable()
            .subscribe(onNext: { [weak self] model in
                self?.updateUI(with: model)
            })
            .disposed(by: disposeBag)
    
        model.value = getModel()
    }
    
    func updateUI(with model: Model?) { ... }
    func getModel() -> Model { ... }
    

    第一种使用 var 的方式十分常见,在 ViewController 中监听 Model 的变化,然后刷新页面。

    第二种使用 Variable 则是 RxSwift 独有的。Variable 几乎提供了 var 的所有功能。另外,加上一条非常重要的特性,就是可以通过调用 asObservable() 方法转换成序列。然后你可以对这个序列应用操作符,来合成其他的序列。所以,如果我们声明的变量需要提供 Rx 支持,那就选用 Variable 这个类型。

    Variable 封装了一个 BehaviorSubject,所以它会持有当前值,并且 Variable 会对新的观察者发送当前值。它不会产生 error 事件。Variable 在 deinit 时,会发出一个 completed 事件。

    ControlProperty

    ControlProperty 专门用于描述 UI 控件属性的,它具有以下特征:

    • 不会产生 error 事件
    • 一定在 MainScheduler 订阅(主线程订阅)
    • 一定在 MainScheduler 监听(主线程监听)
    • 共享状态变化

    相关文章

      网友评论

          本文标题:可被监听的序列也是观察者

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