美文网首页
四、Working with Subjects(Rx.play

四、Working with Subjects(Rx.play

作者: 七夕猪 | 来源:发表于2016-06-22 18:03 被阅读169次

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

    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翻译)

    相关文章

      网友评论

          本文标题:四、Working with Subjects(Rx.play

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