代码之家  ›  专栏  ›  技术社区  ›  Nominalista

retryWhen未按预期重新订阅源

  •  0
  • Nominalista  · 技术社区  · 6 年前

    我在写逻辑,每隔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 方法创建对服务器的请求。

    statusRequestDelay 实际上)我没有向服务器发出请求。每隔t秒它返回相同的 someObject . 如果我更换 获取对象状态 有:

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

    它工作得很好,这意味着它每t秒发出一次服务器请求。它看起来像第一个,原创的 Observable 不是重复。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Daniel T.    6 年前

    问题在于 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()
        }
    }
    

    在链中使用上述方法将导致“called 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)) 是重新订阅的内容,因此每次都返回相同的内容。

    把电话隐藏在平面图中是可行的,因为它是 .just(Void()) 这意味着flatMap的内容被再次调用。