extension URLSession {
fileprivate func loadRepositories(resource: URL) -> Observable<SearchRepositoriesResponse> {
return self
.rx.response(request: URLRequest(url: resource))
.retry(3)
.map(Repository.parse)
.retryWhen { $0.delay(1.0, scheduler: MainScheduler.instance) }
}
}
Perché dovrei usare retryWhen { $0.delay(1.0, scheduler: MainScheduler.instance) }
all'ultimo passo? Cosa succede se non lo uso?
risposte:
0 per risposta № 1Se Repository.parse
restituisce un errore, il retryWhen
nel tuo esempio di codice ritarda l'emissione dell'errore di 1 secondo. IMHO l'uso di retryWhen
l'operatore è un po 'fuorviante in questo caso, perché non si verificano tentativi. Ritarda solo l'errore.
Il codice di esempio nella pagina github di RxFeedback è stato aggiornato a una nuova versione che esegue effettivamente i tentativi fino a quando non viene raggiunto il numero massimo di tentativi:
extension URLSession {
fileprivate func loadRepositories(resource: URL) -> Observable<SearchRepositoriesResponse> {
// The maximum number of attempts to retry before launch the error
let maxAttempts = 4
return self
.rx
.response(request: URLRequest(url: resource))
.retry(3)
.map(Repository.parse)
.retryWhen { errorTrigger in
return errorTrigger.flatMapWithIndex { (error, attempt) -> Observable<Int> in
if attempt >= maxAttempts - 1 {
return Observable.error(error)
}
return Observable<Int>
.timer(Double(attempt + 1), scheduler: MainScheduler.instance).take(1)
}
}
}
}
Ora, quando Repository.parse
restituisce un errore, retryWhen
provoca un nuovo tentativo quando il numero massimo dii tentativi non sono stati raggiunti. Il tentativo ha un ritardo che si allunga ad ogni tentativo. Quando viene raggiunto il numero massimo di tentativi, viene emesso un errore e termina la sequenza principale con un errore.