RxSwift学习教程之类型对象Subject详解

2020-01-08 23:39:27于海丽

另外,当 PublishSubject 对象生命周期结束时,无论后续是否继续有数据产生该对象只会简单的发送之前结束生命周期的事件。


// 结束生命周期
subject.onCompleted()

// 发送新数据
subject.onNext("5")

// 结束观察
subscriptionTwo.dispose()

let disposeBag = DisposeBag()
// 重新进行订阅操作 
subject
 .subscribe { 
  print("3)", $0.element ?? $0) 
 } 
 .addDisposableTo(disposeBag)
// 发送新数据
subject.onNext("?")

/* 打印结果
2) completed
3) completed
 */

对于时序敏感的操作来说,PublishSubject 显然是非常合适的选择。但是并不是所有的情形都时序敏感,有时候我们可能会希望在订阅时能够获知最近一次的数据。此时,我们就需要使用 BehaviorSubject 对象了。

BehaviorSubject

BehaviorSubject 的行为与 PublishSubject 几乎一致,不过前者会给订阅者多发送一个最近的数据。图解如下:

rxswift,rx,subject,教程

图示中最上面对应的是所发射的数据,其中第二行表示第一个观察者,第三行则表示另一个。可以发现第一个观察者是在 1 之后 2 之前进行观察的,但是它依然能够获取到数据 1 。我们可以通过代码进行验证:


let subject = BehaviorSubject(value: "1")
let bag = DisposeBag()

subject
 .subscribe { event in
   print("1) event: (event.element!) ")
 }
 .addDisposableTo(bag)

subject
 .subscribe { event in
  print("2) event: (event.element!) ")
 }
 .addDisposableTo(bag)

subject.onNext("2")

subject
 .subscribe { event in
  print("3) event: (event.element!) ")
 }
 .addDisposableTo(bag)

subject.onNext("3")

因为始终都能获取到最近的数据,所以对于那些可能需要默认值的场景,BehaviorSubject 显然是一个好的选择。

ReplaySubject

ReplaySubject 与 BehaviorSubject 的行为非常接近,只不过前者允许订阅者获取多于 1 个的最近数据。所以从某种意义上来说,后者是前者的一个特例。

下图就是一个 buffer 大小为 2 的 ReplaySubject 对象。它总过发射了三次数据,其中第一个观察者获取了所以的数据。而第二个观察者虽然是在第二个数据发射后才开始,但它依旧能获取缓存区中保存的数据。

rxswift,rx,subject,教程

代码表示如下:


let subject = ReplaySubject<String>.create(bufferSize: 2)

let bag = DisposeBag()

subject
 .subscribe { event in
  print("1) event: (event.element!) ")
 }
 .addDisposableTo(bag)

subject.onNext("1")

subject.onNext("2")

subject
 .subscribe { event in
  print("2) event: (event.element!) ")
 }
 .addDisposableTo(bag)

subject.onNext("3")

/* 打印结果:
1) event: 1 
1) event: 2 
2) event: 1 
2) event: 2 
1) event: 3 
2) event: 3 
*/