Just ask who else is there right now? 45 degrees up in the sky, damn it! My charm with no place to put it!

  • RxSwift (1) — Preliminary study
  • RxSwift (2) – Core logic source code analysis
  • RxSwift (3) – How the Observable sequence is created
  • RxSwift (4) — Higher Order functions (1)
  • RxSwift (5) — Higher Order functions (lower)
  • RxSwift (6) — Scheduler source scheduler
  • RxSwift (7) — Scheduler scheduler
  • RxSwift (8) — KVO Low-level Exploration (1)
  • RxSwift (9) — KVO Low-level Exploration (2)
  • RxSwift (10) — Summary of scene sequences
  • RxSwift (11) — Dispose source code parsing
  • RxSwift (12) — Subject is both offensive and defensive
  • RxSwift (13) — Climb over the pit
  • RxSwift (14) — MVVM bidirectional binding

RxSwift directory through train — Harmonious learning, not impatient!


This article continues with the previous article: RxSwift- higher-order functions (on) to introduce you to RxSwift is very important higher-order functions, not to say more, to introduce

5: Operator to recover from observable error notifications

5.1: catchErrorJustReturn

  • Recover from an error event by returning an observable sequence that emits a single element and then terminates
print("*****catchErrorJustReturn*****")
let sequenceThatFails = PublishSubject<String>()

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

sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // Normal sequence sent successfully
// Send the failed sequence, once the subscription is in place to return the wrong preplan we set earlier
sequenceThatFails.onError(self.lgError) 
Copy the code

5.2: catchError

  • Recover from error events by switching to the provided recovery observable sequence
print("*****catchError*****")
let recoverySequence = PublishSubject<String>()

sequenceThatFails
    .catchError {
        print("Error:", $0)
        return recoverySequence  // Get the error sequence - we are done with the closure in the middle and return the desired sequence (showAlert)
    }
    .subscribe { print($0) }
    .disposed(by: disposeBag)

sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // Normal sequence sent successfully
sequenceThatFails.onError(lgError) // Send the failed sequence

recoverySequence.onNext("CC")
Copy the code

5.3: retry

  • Recover repeated error events by resubscribing to the observable sequence indefinitely
print("*****retry*****")
var count = 1 // External variable control process
let sequenceRetryErrors = Observable<String>.create { observer in
    observer.onNext("Hank")
    observer.onNext("Kody")
    observer.onNext("CC")
    
    if count= =1 { 
        // Once the process comes in, it overflows - the condition here can be used as an exit, the number of failures
        observer.onError(self.lgError)  // Error sequence received, retry sequence occurred
        print("Here comes the wrong sequence.")
        count+ =1
    }
    
    observer.onNext("Lina")
    observer.onNext("Little Wild Goose")
    observer.onNext("Tingting")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceRetryErrors
    .retry()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
Copy the code

5.4: retry (_) :

  • Repeatedly recover from the error event by re-subscribing to the observable sequence until the number of retries is reachedmaxThe attempted counting
print("*****retry(_:)*****")
let sequenceThatErrors = Observable<String>.create { observer in
    observer.onNext("Hank")
    observer.onNext("Kody")
    observer.onNext("CC")
    
    if count < 5 { // The error exit set here is meaningless because we set the number of retries
        observer.onError(self.lgError)
        print("Here comes the wrong sequence.")
        count+ =1
    }
    
    observer.onNext("Lina")
    observer.onNext("Little Wild Goose")
    observer.onNext("Tingting")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceThatErrors
    .retry(3)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
Copy the code

6: Rx process operator.

6.1: the debug

  • Prints all subscriptions, events, and processing.
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("Here comes the wrong sequence.")
        count+ =1
    }
    
    observer.onNext("Lina")
    observer.onNext("Little Wild Goose")
    observer.onNext("Can")
    observer.onCompleted()
    
    return Disposables.create()
}

sequenceThatErrors
    .retry(3)
    .debug()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
Copy the code

6.2: RxSwift. Resources. Total:

  • Provides a count of all Rx resource allocations, which is useful for detecting leaks during development.
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)
Copy the code

7: link operator

7.1: multicast

  • Converts a source observable sequence to a connectable sequence and broadcasts its emission through the specified topic.
func testMulticastConnectOperators(a){
    print("*****multicast*****")
    let subject = PublishSubject<Any>()
    subject.subscribe{print("00.\ [$0)")}
        .disposed(by: disposeBag)
    
    let netOB = Observable<Any>.create { (observer) -> Disposable in
            sleep(2)// Simulate network latency
            print("I'm starting to request the Internet.")
            observer.onNext("Requested Network data")
            observer.onNext("Requested local")
            observer.onCompleted()
            return Disposables.create {
                print("Destroy callback.")
            }
        }.publish()
    
    netOB.subscribe(onNext: { (anything) in
            print(Subscribe to 1: "",anything)
        })
        .disposed(by: disposeBag)

    // We sometimes subscribe more than once, because sometimes our data may be used in different ways
    // So what happens when you subscribe once?
    netOB.subscribe(onNext: { (anything) in
            print("Subscription 2:",anything)
        })
        .disposed(by: disposeBag)
    
    _ = netOB.connect()
}
Copy the code
  • The underlying logic explores intermediate variablesConnectableObservableAdapterSave theThe source sequence source,makeSubject
  • Subscribe to the processself.lazySubject.subscribe(observer)A lazy-loaded sequence guarantees intermediate variablesConnectableObservableAdapterIt’s the same response sequence every time
  • The rest isPublishSubjectSubscription effect of
  • Completion waits for the response from the source sequence, but our source sequence’s subscription is inconnectInside the function! If not calledconnectFunction, meaning the response will never be sent. The logic behind this is that all the previous sent responses are inconnectNone of the preceding functions make any sense!
  • So that explains ourpublishIs shared state:connnectOnce our sequence sends a response (for all subscriptions).

7.2: replay

  • Converts the source observable sequence to a concatenable sequence, and the buffer size previously emitted is replayed to each new subscription server
  • First to own andpublishSame ability, sharedObservable sequenceSecondly usereplayWe also need to pass in a parameter(buffer size)To cache events that have been sent, and when a new subscriber subscribes, the cached event is sent to the new subscriber
func testReplayConnectOperators(a){   
    print("*****replay*****")

    let interval = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance).replay(5)
    
    interval.subscribe(onNext: { print(Date.time,"Subscription: 1, event:\ [$0)") })
        .disposed(by: self.disposeBag)
    
    delay(2) { _ = interval.connect() }
    
    delay(4) {
        interval.subscribe(onNext: { print(Date.time,"Subscription: 2, events:\ [$0)") })
            .disposed(by: self.disposeBag)
    }
    
    delay(8) {
        interval.subscribe(onNext: { print(Date.time,"Subscription: 3, events:\ [$0)") })
            .disposed(by: self.disposeBag)
    }
    delay(20, closure: {
        self.disposeBag = DisposeBag()})/** subscribe: 0 2019-05-28 21-32-42 subscribe: 0 2019-05-28 21-32-42 subscribe: 0 2019-05-28 21-32-42 subscribe: 0 2019-05-28 21-32-42 subscribe: 0 2019-05-28 21-32-42 subscribe: 0 2019-05-28 21-32-42 2, event: 1 the 21 2019-05-28-32-45 subscription: 2, events: 4 21 2019-05-28-32-46 subscription: 3, events: 0 2019-05-28 21-32-46 subscription: 3, events: 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 2019-05-28 21-32-46 4 // Sequence starts from 0 // Timer also has no fault sub2 sub3 and sub1 are synchronized */
}
Copy the code

The use of higher-order functions is somewhat interesting! If you are new to RxSwift, it is highly recommended that you patiently practice, it will definitely help your development!

Just ask who else is there right now? 45 degrees up in the sky, damn it! My charm with no place to put it!