首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RxSwift RetryWhen导致可重入性异常

RxSwift RetryWhen导致可重入性异常
EN

Stack Overflow用户
提问于 2019-02-25 13:27:03
回答 1查看 1.5K关注 0票数 3

我一直在尝试测试RxSwift上的retryWhen操作符,我遇到了Reentrancy Anomaly问题,代码如下:

代码语言:javascript
复制
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)

使用上面的代码,它提供了:

代码语言:javascript
复制
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

只是想知道有没有人知道这个问题的原因?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-26 04:22:09

正如控制台注释所解释的那样,可以使用.observeOn(MainScheduler.asyncInstance)取消此警告,如下所示:

代码语言:javascript
复制
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)")
    })

我擅自对您的示例代码做了一些细微的调整,以展示编写代码的另一种方法。

更多信息

您要求解释(a)添加ObserveOn的原因和(b)为什么需要它。

.observeOn(MainScheduler.asyncInstance)所做的是将请求路由到另一个线程,在那里事件可以完成,然后在主线程上再次发出事件。换句话说,就像这样做:

代码语言:javascript
复制
.observeOn(backgroundScheduler).observeOn(MainScheduler.instance)

其中backgroundScheduler的定义如下:

代码语言:javascript
复制
let backgroundScheduler = SerialDispatchQueueScheduler(qos: .default)

至少这是我的理解。

至于为什么需要它,我不能说。您可能在库中发现了一个bug,因为使用1秒的延迟可以在没有observeOn的情况下工作得很好。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54859977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档