Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

451
Vistas
RxSwift RetryWhen causa una anomalía de reentrada

He estado tratando de probar el operador retryWhen en RxSwift y me he encontrado con el Reentrancy Anomaly de reentrada, aquí está el código:

 Observable<Int>.create { observer in observer.onNext(1) observer.onNext(2) observer.onNext(3) observer.onNext(4) observer.onError(RequestError.dataError) return Disposables.create() } .retryWhen { error in return error.enumerated().flatMap { (index, error) -> Observable<Int> in let maxRetry = 1 print("index: \(index)") return index < maxRetry ? Observable.timer(1, scheduler: MainScheduler.instance) : Observable.error(RequestError.tooMany) } } .subscribe(onNext: { value in print("This: \(value)") }, onError: { error in print("ERRRRRRR: \(error)") }) .disposed(by: disposeBag)

Con el código de arriba da:

 This: 1 This: 2 This: 3 This: 4 index: 0 This: 1 This: 2 This: 3 This: 4 index: 1 ⚠️ Reentrancy anomaly was detected. > Debugging: To debug this issue you can set a breakpoint in /Users/tony.lin/Documents/Snippet/MaterialiseTest/Pods/RxSwift/RxSwift/Rx.swift:97 and observe the call stack. > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?` This behavior breaks the grammar because there is overlapping between sequence events. Observable sequence is trying to send an event before sending of previous event has finished. > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in the expected way. > Remedy: If this is the expected behavior this message can be suppressed by adding `.observeOn(MainScheduler.asyncInstance)` or by enqueing sequence events in some other way. ⚠️ Reentrancy anomaly was detected. > Debugging: To debug this issue you can set a breakpoint in /Users/tony.lin/Documents/Snippet/MaterialiseTest/Pods/RxSwift/RxSwift/Rx.swift:97 and observe the call stack. > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?` This behavior breaks the grammar because there is overlapping between sequence events. Observable sequence is trying to send an event before sending of previous event has finished. > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in the expected way. > Remedy: If this is the expected behavior this message can be suppressed by adding `.observeOn(MainScheduler.asyncInstance)` or by enqueing sequence events in some other way. ERRRRRRR: tooMany

Solo me preguntaba si alguien sabe la causa de este problema.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Como explica el comentario de la consola, esta advertencia se puede suprimir usando .observeOn(MainScheduler.asyncInstance) como en:

 Observable<Int>.from([1, 2, 3, 4]).concat(Observable.error(RequestError.dataError)) .observeOn(MainScheduler.asyncInstance) // this is the magic that makes it work. .retryWhen { error in return error.enumerated().flatMap { (index, error) -> Observable<Int> in let maxRetry = 1 print("Index:", index) guard index < maxRetry else { throw RequestError.tooMany } return Observable.timer(1, scheduler: MainScheduler.instance) } } .subscribe(onNext: { value in print("This: \(value)") }, onError: { error in print("ERRRRRRR: \(error)") })

Me tomé la libertad de hacer algunos ajustes menores a su código de ejemplo para mostrar una forma alternativa de escribir lo que tiene.

información adicional

Usted pidió explicar (a) por qué funciona agregar ObserveOn y (b) por qué es necesario.

Lo que .observeOn(MainScheduler.asyncInstance) es enrutar la solicitud a un subproceso alternativo donde el evento puede finalizar y luego emitir el evento nuevamente en el subproceso principal. En otras palabras, es como hacer esto:

 .observeOn(backgroundScheduler).observeOn(MainScheduler.instance)

Donde backgroundScheduler se define como:

 let backgroundScheduler = SerialDispatchQueueScheduler(qos: .default)

Al menos eso es lo que entiendo.

En cuanto a por qué es necesario, no puedo decirlo. Es posible que haya encontrado un error en la biblioteca porque el uso de un retraso de 1 segundo funciona bien sin observeOn.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda