四、Working with Subjects(Rx.playground翻译)

注意:使用本例中的代码首先应该导入头文件,代码如下:

import RxSwift

Working with Subjects

Subject 是一个桥梁或者代理,在 Rx 的某些实现里可见,它同时扮演了观察者和Observable的角色。因为它是一个观察者,所以它可以订阅一个或多个Observables,因为它又是一个Observable,所以它可以回收它自己观察的 item,还可以发出新的 items。了解更多
Tips: 能力有限,上面的翻译的不是清楚。可以看看作者 yaqing函数响应式编程框架RxSwift 学习——Subject 这篇文章,以便理解。

extension ObservableType {
    /**
         Add observer with `id` and print each emitted event.
         - parameter id: an identifier for the subscription.
     */
    func addObserver(_ id: String) -> Disposable {
        return subscribe { print("Subscription:", id, "Event:", $0) }
    }
}

func writeSequenceToConsole<O: ObservableType>(name: String, sequence: O) -> Disposable {
    return sequence.subscribe { event in
        print("Subscription: \(name), event: \(event)")
    }
}

上面的这段代码只是辅助理解,方便测试。


PublishSubject

在所有的观察者订阅之后广播新的事件。意思是说,每个观察者只能观察到在自己订阅之后Observable发出的事件。

image

example("PublishSubject") {
    let disposeBag = DisposeBag()
    let subject = PublishSubject<String>()

    subject.addObserver("1").addDisposableTo(disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")

    subject.addObserver("2").addDisposableTo(disposeBag)
    subject.onNext("⚽️")
    subject.onNext("🏀")
}

Debug Area 输出:
--- PublishSubject example ---
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 1 Event: next(⚽️)
Subscription: 2 Event: next(⚽️)
Subscription: 1 Event: next(🏀)
Subscription: 2 Event: next(🏀)

Tips: 这个例子还介绍了使用onNext(_:)便利方法,这个方法相当于on(.next(_:))方法,这两个方法会导致一个提供element的新事件被发散到订阅者们上。还有onError(_:)onCompleted()便利方法,分别相当于on(.error(_:))方法和on(.completed)方法。


ReplaySubject

广播新事件到所有的订阅者们上,并且可以把 指定bufferSize数量的在新订阅者订阅之前广播的事件发送到新订阅者上。

image

example("ReplaySubject") {
    let disposeBag = DisposeBag()
    let subject = ReplaySubject<String>.create(bufferSize: 1)

    subject.addObserver("1").addDisposableTo(disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")

    subject.addObserver("2").addDisposableTo(disposeBag)
    subject.onNext("⚽️")
    subject.onNext("🏀")
}

Debug Area 输出:
--- ReplaySubject example ---
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
example("BehaviorSubject") {
    let disposeBag = DisposeBag()
    let subject = BehaviorSubject(value: "🔴")

    subject.addObserver("1").addDisposableTo(disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")

    subject.addObserver("2").addDisposableTo(disposeBag)
    subject.onNext("⚽️")
    subject.onNext("🏀")

    subject.addObserver("3").addDisposableTo(disposeBag)
    subject.onNext("🍐")
    subject.onNext("🍊")
}

Debug Area 输出:
--- BehaviorSubject example ---
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(🍊)

注意到在前面这些例子中少了些什么吗?一个 Completed 事件。当PublishSubjectReplaySubjectBehaviorSubject即将被处理的时候,它们不会自动发出 Completed 事件。


Variable

封装一个BehaviorSubject,所以它将首先发送最近的一个(或者默认的)值到新的订阅者们然后再发送订阅之后的事件。并且Variable还会维护当前值的状态。Variable将不会发出 Error 事件。然而,它将会自动地发出一个 Completed 事件并且终止于 deinit

example("Variable") {
    let disposeBag = DisposeBag()
    let variable = Variable("🔴")

    variable.asObservable().addObserver("1").addDisposableTo(disposeBag)
    variable.value = "🐶"
    variable.value = "🐱"

    variable.asObservable().addObserver("2").addDisposableTo(disposeBag)
    variable.value = "⚽️"
    variable.value = "🏀"
}

Debug Area 输出:
--- Variable example ---
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: 1 Event: completed
Subscription: 2 Event: completed

调用Variable实例的asObservable()方法是为了访问BehaviorSubject序列的底层。Variable不会实现on操作(或者 onNext(_:)),而是暴露一个可以获取当前值的属性。设置一个新值还会添加这个值到它的底层BehaviorSubject序列。


下一篇: 五、联合操作-Combination Operators(Rx.playground翻译)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文章内部分图片资源来自RayWenderlich.com 本文结合自己的理解来总结介绍一下RxSwift最基本的...
    FKSky阅读 7,951评论 4 14
  • 首先,何为RxSwift? RxSwift是ReactiveX的Swift版本,一个响应式变成框架。传送门 开始之...
    cocoawork丶阅读 3,273评论 0 3
  • 发现 关注 消息 RxSwift入坑解读-你所需要知道的各种概念 沸沸腾关注 2016.11.27 19:11*字...
    枫叶1234阅读 7,809评论 0 2
  • 最近在学习RxSwift相关的内容,在这里记录一些基本的知识点,以便今后查阅。 Observable 在RxSwi...
    L_Zephyr阅读 5,721评论 1 4
  • 虚度了无数个假期后,内心满满的罪恶感,痛定思痛后决定洗心革面重新做人,每一天都计划好,坚决不再浪费生命。 ...
    古丽Lily阅读 4,474评论 12 7