RxSwift(5)— 高階函數(下)

就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!swift


RxSwift 目錄直通車 --- 和諧學習,不急不躁!緩存


這一篇文章繼續上一篇:RxSwift-高階函數(上)給你們介紹 RxSwift 很是重要的高階函數,也很少說,開始介紹服務器

5:從可觀察對象的錯誤通知中恢復的操做符

5.1:catchErrorJustReturn

  • 從錯誤事件中恢復,方法是返回一個可觀察到的序列,該序列發出單個元素,而後終止
print("*****catchErrorJustReturn*****")
let sequenceThatFails = PublishSubject<String>()

sequenceThatFails
    .catchErrorJustReturn("Cooci")
    .subscribe { print($0) }
    .disposed(by: disposeBag)

sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // 正常序列發送成功的
//發送失敗的序列,一旦訂閱到位 返回咱們以前設定的錯誤的預案
sequenceThatFails.onError(self.lgError) 
複製代碼

5.2:catchError

  • 經過切換到提供的恢復可觀察序列,從錯誤事件中恢復
print("*****catchError*****")
let recoverySequence = PublishSubject<String>()

sequenceThatFails
    .catchError {
        print("Error:", $0)
        return recoverySequence  // 獲取到了錯誤序列-咱們在中間的閉包操做處理完畢,返回給用戶須要的序列(showAlert)
    }
    .subscribe { print($0) }
    .disposed(by: disposeBag)

sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // 正常序列發送成功的
sequenceThatFails.onError(lgError) // 發送失敗的序列

recoverySequence.onNext("CC")
複製代碼

5.3:retry

  • 經過無限地從新訂閱可觀察序列來恢復重複的錯誤事件
print("*****retry*****")
var count = 1 // 外界變量控制流程
let sequenceRetryErrors = Observable<String>.create { observer in
    observer.onNext("Hank")
    observer.onNext("Kody")
    observer.onNext("CC")
    
    if count == 1 { 
        // 流程進來以後就會過分-這裏的條件能夠做爲出口,失敗的次數
        observer.onError(self.lgError)  // 接收到了錯誤序列,重試序列發生
        print("錯誤序列來了")
        count += 1
    }
    
    observer.onNext("Lina")
    observer.onNext("小雁子")
    observer.onNext("婷婷")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceRetryErrors
    .retry()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
複製代碼

5.4:retry(_:):

  • 經過從新訂閱可觀察到的序列,重複地從錯誤事件中恢復,直到重試次數達到max未遂計數
print("*****retry(_:)*****")
let sequenceThatErrors = Observable<String>.create { observer in
    observer.onNext("Hank")
    observer.onNext("Kody")
    observer.onNext("CC")
    
    if count < 5 { // 這裏設置的錯誤出口是沒有太多意義的額,由於咱們設置重試次數
        observer.onError(self.lgError)
        print("錯誤序列來了")
        count += 1
    }
    
    observer.onNext("Lina")
    observer.onNext("小雁子")
    observer.onNext("婷婷")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceThatErrors
    .retry(3)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
複製代碼

6:Rx流程操做符。

6.1:debug

  • 打印全部訂閱、事件和處理。
print("*****debug*****")
var count = 1

let sequenceThatErrors = Observable<String>.create { observer in
    observer.onNext("Hank")
    observer.onNext("Kody")
    observer.onNext("CC")
    
    if count < 5 {
        observer.onError(self.lgError)
        print("錯誤序列來了")
        count += 1
    }
    
    observer.onNext("Lina")
    observer.onNext("小雁子")
    observer.onNext("可心")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceThatErrors
    .retry(3)
    .debug()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
複製代碼

6.2: RxSwift.Resources.total:

  • 提供全部Rx資源分配的計數,這對於在開發期間檢測泄漏很是有用。
print("*****RxSwift.Resources.total*****")

print(RxSwift.Resources.total)

let subject = BehaviorSubject(value: "Cooci")

let subscription1 = subject.subscribe(onNext: { print($0) })

print(RxSwift.Resources.total)

let subscription2 = subject.subscribe(onNext: { print($0) })

print(RxSwift.Resources.total)

subscription1.dispose()

print(RxSwift.Resources.total)

subscription2.dispose()

print(RxSwift.Resources.total)
複製代碼

7:連接操做符

7.1:multicast

  • 將源可觀察序列轉換爲可鏈接序列,並經過指定的主題廣播其發射。
func testMulticastConnectOperators(){
    print("*****multicast*****")
    let subject = PublishSubject<Any>()
    subject.subscribe{print("00:\($0)")}
        .disposed(by: disposeBag)
    
    let netOB = Observable<Any>.create { (observer) -> Disposable in
            sleep(2)// 模擬網絡延遲
            print("我開始請求網絡了")
            observer.onNext("請求到的網絡數據")
            observer.onNext("請求到的本地")
            observer.onCompleted()
            return Disposables.create {
                print("銷燬回調了")
            }
        }.publish()
    
    netOB.subscribe(onNext: { (anything) in
            print("訂閱1:",anything)
        })
        .disposed(by: disposeBag)

    // 咱們有時候不止一次網絡訂閱,由於有時候咱們的數據可能用在不一樣的額地方
    // 因此在訂閱一次 會出現什麼問題?
    netOB.subscribe(onNext: { (anything) in
            print("訂閱2:",anything)
        })
        .disposed(by: disposeBag)
    
    _ = netOB.connect()
}
複製代碼
  • 底層邏輯探索中間變量ConnectableObservableAdapter保存了源序列source中間序列makeSubject
  • 訂閱流程self.lazySubject.subscribe(observer)一個懶加載的序列,保證了中間變量ConnectableObservableAdapter每一次都是同一個響應序列
  • 剩下就是PublishSubject的訂閱效果
  • 完事等待源序列的響應,可是咱們的源序列的訂閱是在connect函數裏面!若是沒有調用connect函數,意味着就永遠不會發送響應。這樣背後的邏輯就是,前面因此的發送響應在connect函數以前的都沒有任何的意義!
  • 以上也就說明了咱們的publish就是狀態共享的:connnect一次咱們序列發送一次響應(響應全部訂閱)。

7.2:replay

  • 將源可觀察序列轉換爲可鏈接的序列,並將向每一個新訂閱服務器重放之前排放的緩衝大小
  • 首先擁有和publish同樣的能力,共享 Observable sequence, 其次使用replay還須要咱們傳入一個參數(buffer size)來緩存已發送的事件,當有新的訂閱者訂閱了,會把緩存的事件發送給新的訂閱者
func testReplayConnectOperators(){   
    print("*****replay*****")

    let interval = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance).replay(5)
    
    interval.subscribe(onNext: { print(Date.time,"訂閱: 1, 事件: \($0)") })
        .disposed(by: self.disposeBag)
    
    delay(2) { _ = interval.connect() }
    
    delay(4) {
        interval.subscribe(onNext: { print(Date.time,"訂閱: 2, 事件: \($0)") })
            .disposed(by: self.disposeBag)
    }
    
    delay(8) {
        interval.subscribe(onNext: { print(Date.time,"訂閱: 3, 事件: \($0)") })
            .disposed(by: self.disposeBag)
    }
    delay(20, closure: {
        self.disposeBag = DisposeBag()
    })
    
    /** 訂閱: 1, 事件: 4 訂閱: 1, 事件: 0 2019-05-28 21-32-42 訂閱: 2, 事件: 0 2019-05-28 21-32-42 訂閱: 1, 事件: 1 2019-05-28 21-32-42 訂閱: 2, 事件: 1 2019-05-28 21-32-45 訂閱: 2, 事件: 4 2019-05-28 21-32-46 訂閱: 3, 事件: 0 2019-05-28 21-32-46 訂閱: 3, 事件: 1 2019-05-28 21-32-46 訂閱: 3, 事件: 2 2019-05-28 21-32-46 訂閱: 3, 事件: 3 2019-05-28 21-32-46 訂閱: 3, 事件: 4 // 序列從 0開始 // 定時器也沒有斷層 sub2 sub3 和 sub1 是同步的 */
}
複製代碼

高階函數的用法仍是有點意思的!若是你是一個RxSwift新手,仍是很是建議你們耐着性子好好練習,對你的開發絕對有幫助!網絡

就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!閉包

相關文章
相關標籤/搜索