The retry operator

The retry operator does not really handle the error. It just ignores it, and it will resubscribe to an Observable that emits an error. Let's start with the implementation. We will define a shouldEmitError that equals true, which we will use as a quick way to prevent our sequence subscription from retrying indefinitely in this example. Now we will create an Observable sequence of the Int type, as follows:

example(for: "retry") {
let disposeBag = DisposeBag()
var shouldEmitError = true

let observableSeq = Observable<Int>.create{ observer in

}
}

We will add two next events to the observer, which will be emitted to the subscribers. This is another way to create an Observable sequence using create and manually building it up with next error and/or completed events:

let observableSeq = Observable<Int>.create{ observer in
observer.onNext(10)
observer.onNext(20)
}

create takes a closure parameter that takes an observer and returns a disposable and create returns an Observable. We don't have to do anything to disposable returned by the closure, such as adding it to the disposeBag. The observable sequence is handled normally; in other words, normal rules apply. So we will use disposables create operator to return disposable that does nothing on disposal. It's good to have some sense of the inner workings, but don't get too hung up on it if it is too elusive, especially when you first start working with it. So we have added a couple of next events and now we will conditionally add an error event. We will check to see whether  shouldEmitError is true, which it is initially, and if so, we will create and add an error event and then set shouldEmitError to false. We will use a retry operator in a moment. When this error event is encountered, subscribers will be resubscribed and the sequence will start emitting from the beginning, but the error event will not be emitted again, because shouldEmitError will be false. So far, our code looks like this:

let observableSeq = Observable<Int>.create { observer in
observer.onNext(10)
observer.onNext(20)

if shouldEmitError{
observer.onError(CustomError.test)
shouldEmitError = false
}
return Disposables.create()
}

We will add a next and completed event that will be emitted upon resubscription, as follows:

if shouldEmitError{
observer.onError(CustomError.test)
shouldEmitError = false
}

observer.onNext(30)
observer.onCompleted()

return Disposables.create()
}

Now that we have created the Observable sequence, we will subscribe to it and print out emitted events, as follows:

example(for: "retry") {
let disposeBag = DisposeBag()
var shouldEmitError = true

let observableSeq = Observable<Int>.create { observer in
observer.onNext(10)
observer.onNext(20)

if shouldEmitError{
observer.onError(CustomError.test)
shouldEmitError = false
}

observer.onNext(30)
observer.onCompleted()

return Disposables.create()
}

observableSeq.subscribe{ print($0) }
.disposed(by: disposeBag)
}

In the console log, note that the Observable sequence emits the error and terminates, as illustrated:

We will insert the retry operator before the subscription, as shown:

example(for: "retry") {
let disposeBag = DisposeBag()
var shouldEmitError = true

let observableSeq = Observable<Int>.create { observer in
observer.onNext(10)
observer.onNext(20)

if shouldEmitError{
observer.onError(CustomError.test)
shouldEmitError = false
}

observer.onNext(30)
observer.onCompleted()

return Disposables.create()
}

observableSeq.retry()
.subscribe{ print($0) }
.disposed(by: disposeBag)
}

Also, the subscriber will be resubscribed, the error event will not be emitted the second time, so the third next event will be emitted and then the sequence will terminate with the completed event, as in the following screenshot:

The retry operator will retry repeatedly infinitely until it successfully terminates with a completed event. If you want to limit the number of retries, you can use the overload of retry that takes a maxAttemptsCount integer parameter. This is a little unintuitive though, since the operator name is retry but the integer you pass is the total number of times the subscription will be attempted. In other words, if you want to subscribe and then retry once if the subscription emits error, pass in the value of 2 to retry. As we mentioned, Drivers guarantee not to fail, that is, terminate with an error event. This does not mean that it somehow magically prevents errors from happening. It just means that Drivers will require you to preemptively determine what to do in case an error does occur. Similar to regular Observable sequences, Drivers can just return sequences that emit a single element and terminate. We are talking about onErrorJustReturn, which we have already used a few times, but now we will specifically look at its implementation and usage.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset