RxSwift (二) Working with Subjects

敖老黑發表於2018-01-03

首先在playground 中給ObervableType增加一個擴充套件。方便檢視子類訂閱時發生的變化

extension ObservableType{

    ///給每一個觀察者增加一個id。並列印id和發射的事件
    func addObservable(_ 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

PublishSubject只會把在訂閱發生的時間點之後來自原始Observable的資料發射給觀察者。

exampleOf(description: "PublishSubject") { 
    
    let disposeBag = DisposeBag()
    
    let publishSubject = PublishSubject<String>()
    
    ///第一組
    publishSubject.addObservable("no.1").disposed(by: disposeBag)
    
    publishSubject.onNext("2")
    
    publishSubject.onNext("3")
    
    //第二組
    publishSubject.addObservable("no.2").disposed(by: disposeBag)
    
    publishSubject.onNext("?")
    
    publishSubject.onNext("?")
}

複製程式碼

列印結果如下

------exampleOf:PublishSubject------
Subscription: no.1 Event: next(2)
Subscription: no.1 Event: next(3)
Subscription: no.1 Event: next(?)
Subscription: no.2 Event: next(?)
Subscription: no.1 Event: next(?)
Subscription: no.2 Event: next(?)
複製程式碼

可以看no.2 並沒有收到no.2訂閱之前傳送的訊號(2和3)。

ReplaySubject

ReplaySubject會發射所有來自原始Observable的資料給觀察者,無論它們是何時訂閱的。也 有其它版本的ReplaySubject,在重放快取增長到一定大小的時候或過了一段時間後會丟棄舊 的資料(原始Observable發射的)。

exampleOf(description: "replaySubject") { 
    
    let disposeBag = DisposeBag()
    
    let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
    
    replaySubject.addObservable("no.1").disposed(by: disposeBag)
    
    replaySubject.onNext("第一個事件")
    
    replaySubject.onNext("第二個事件")

    
    
    replaySubject.addObservable("no.2").disposed(by: disposeBag)
    
    replaySubject.onNext("3")
    
    replaySubject.onNext("4")
    
}

複製程式碼

列印結果如下

------exampleOf:replaySubject------
Subscription: no.1 Event: next(第一個事件)
Subscription: no.1 Event: next(第二個事件)
Subscription: no.2 Event: next(第一個事件)
Subscription: no.2 Event: next(第二個事件)
Subscription: no.1 Event: next(3)
Subscription: no.2 Event: next(3)
Subscription: no.1 Event: next(4)
Subscription: no.2 Event: next(4)

複製程式碼

會將訂閱之前的訊號發給新訂閱者。如果指定了buttersize,會根據buttersize(我理解為多少個)傳送之前的資料

BehaviorSubject

當觀察者訂閱BehaviorSubject時,它開始發射原始Observable最近發射的資料(如果此時還 沒有收到任何資料,它會發射一個預設值),然後繼續發射其它任何來自原始Observable的 資料。

exampleOf(description: "BehaviorSubject") { 
    
    let disposeBag = DisposeBag()
    
    let subject = BehaviorSubject(value: "behavior")
    
    subject.addObservable("第一個響應").disposed(by: disposeBag)
    
    subject.onNext("第一個事件")
    
    subject.onNext("第二個事件")
    
    subject.addObservable("第二個響應").disposed(by: disposeBag)
    
    subject.onNext("第三個事件")
    
    subject.onNext("第四個事件")
}

複製程式碼

列印結果

------exampleOf:BehaviorSubject------
Subscription: 第一個響應 Event: next(behavior)
Subscription: 第一個響應 Event: next(第一個事件)
Subscription: 第一個響應 Event: next(第二個事件)
Subscription: 第二個響應 Event: next(第二個事件)
Subscription: 第一個響應 Event: next(第三個事件)
Subscription: 第二個響應 Event: next(第三個事件)
Subscription: 第一個響應 Event: next(第四個事件)
Subscription: 第二個響應 Event: next(第四個事件)
複製程式碼

Variable

Variable是BehaviorSubject的一層封裝。特點不會被顯式終結。即:不會收到 .Completed 和 .Error 這類的終結事件,它會主動在析構的時候傳送 .Complete 。

exampleOf(description: "Variable") { 
    
    let disposeBag = DisposeBag()
    
    let variable = Variable<String>("預設值")
    
    variable.asObservable().addObservable("no.1").disposed(by: disposeBag)
    
    variable.value = "第二個值"
    
    variable.value = "第三個值"
    
    variable.asObservable().addObservable("no.2").disposed(by: disposeBag)
    
    variable.value = "第四個值"
    
    variable.value = "第五個值"
}
複製程式碼

列印結果

------exampleOf:Variable------
Subscription: no.1 Event: next(預設值)
Subscription: no.1 Event: next(第二個值)
Subscription: no.1 Event: next(第三個值)
Subscription: no.2 Event: next(第三個值)
Subscription: no.1 Event: next(第四個值)
Subscription: no.2 Event: next(第四個值)
Subscription: no.1 Event: next(第五個值)
Subscription: no.2 Event: next(第五個值)
Subscription: no.1 Event: completed
Subscription: no.2 Event: completed

複製程式碼

相關文章