简体   繁体   English

retryWhen未按预期重新订阅源

[英]retryWhen is not resubscribing source as expected

I'm writing logic for checking status of an object every t seconds until it's completed. 我正在编写逻辑,用于每t秒检查一次对象的状态,直到完成为止。 I decided to use retryWhen operator. 我决定使用retryWhen运算符。

getObjectStatus(someObject: someObjectInstance)
    .flatMap { someObject -> Observable<SomeObject> in
        if someObject.status == .notProcessed {
            return .error(SomeObjectNotProcessed())
        } else {
            return .just(someObject)
        }
    }
    .retryWhen { errors -> Observable<Void> in
        let retry = errors.enumerated().flatMap { retryCount, error -> Observable<Void> in
            guard retryCount < statusRequestCount else {
                print("The maximum number of request has been reached.")
                return .error(error)
            }

            if error is SomeObjectNotProcessed {
                return Observable.just(Void())
                        .delay(statusRequestDelay, scheduler: BackgroundScheduler.instance)
            } else {
                return .error(error)
            }
        }

        return retry
    }
    .subscribeOn(BackgroundScheduler.instance)
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { [weak self] someObject in
        self?.someObjectProcessingSucceeded()
    }, onError: { [weak self] error in
        self?.someObjectProcessingFailed(error: error)
    })
    .disposed(by: disposeBag)

Where the getObjectStatus method create request to the server. 其中getObjectStatus方法向服务器创建请求。

Now the problem is that with this code every t seconds ( statusRequestDelay actually) I'm not making a request to the server. 现在的问题是,每t秒使用此代码(实际上为statusRequestDelay ),我没有向服务器发出请求。 Every t seconds it returns the same instance of someObject . 每隔t秒,它将返回someObject的相同实例。 If I replace getObjectStatus with: 如果我将getObjectStatus替换为:

Observable.just(Void())
    .flatMap { _ in self.getObjectStatus(someObject: someObjectInstance) }

it works perfectly, which means that it makes server request every t seconds. 它完美地工作,这意味着它每隔t秒就发出服务器请求。 It looks like the first, original Observable is not repeating. 看起来像第一个原始的Observable不在重复。

The problem is in how your getObjectStatus function is written. 问题在于如何编写getObjectStatus函数。 Apparently, it returns a .just or some other observable that doesn't actually retry the network call. 显然,它返回一个.just或其他实际上不重试网络调用的观察值。 Without seeing that code I can't give a definitive answer. 没有看到该代码,我无法给出确切的答案。

However notice this: 但是请注意:

func getObjectStatus(someObject: Int) -> Observable<SomeObject> {
    var count = 0
    return Observable.create { observer in
        print("called getObjectStatus")
        if count < 3 {
            observer.onNext(SomeObject(status: .notProcessed))
            observer.onCompleted()
            count += 1
        }
        else {
            observer.onNext(SomeObject(status: .processed))
            observer.onCompleted()
        }
        return Disposables.create()
    }
}

Using the above with your chain will cause "called getObjectStatus" to print 3 times. 将以上内容与您的链一起使用将导致“调用getObjectStatus”打印3次。

While: 而:

var count = 0
func getObjectStatus(someObject: Int) -> Observable<SomeObject> {
    print("called getObjectStatus")
    if count < 3 {
        count += 1
        return Observable.just(SomeObject(status: .notProcessed))
    }
    else {
        return Observable.just(SomeObject(status: .processed))
    }
}

Will not. 将不会。

The difference here is that in the latter case, the .just(SomeObject(status: .notProcessed)) is what is being resubscribed to, so it returns the same thing every time. 此处的区别在于,在后一种情况下, .just(SomeObject(status: .notProcessed))是要重新订阅的内容,因此每次都返回相同的内容。

Burying the call in a flatMap works because it's the .just(Void()) that is getting resubscribed to which means the contents of the flatMap is called again. 在flatMap中隐藏该调用是.just(Void()) ,因为重新获得.just(Void())意味着再次调用flatMap的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM