簡體   English   中英

retryWhen未按預期重新訂閱源

[英]retryWhen is not resubscribing source as expected

我正在編寫邏輯,用於每t秒檢查一次對象的狀態,直到完成為止。 我決定使用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)

其中getObjectStatus方法向服務器創建請求。

現在的問題是,每t秒使用此代碼(實際上為statusRequestDelay ),我沒有向服務器發出請求。 每隔t秒,它將返回someObject的相同實例。 如果我將getObjectStatus替換為:

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

它完美地工作,這意味着它每隔t秒就發出服務器請求。 看起來像第一個原始的Observable不在重復。

問題在於如何編寫getObjectStatus函數。 顯然,它返回一個.just或其他實際上不重試網絡調用的觀察值。 沒有看到該代碼,我無法給出確切的答案。

但是請注意:

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()
    }
}

將以上內容與您的鏈一起使用將導致“調用getObjectStatus”打印3次。

而:

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))
    }
}

將不會。

此處的區別在於,在后一種情況下, .just(SomeObject(status: .notProcessed))是要重新訂閱的內容,因此每次都返回相同的內容。

在flatMap中隱藏該調用是.just(Void()) ,因為重新獲得.just(Void())意味着再次調用flatMap的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM