【问题标题】:Polling to Backend API in regular interval for certain number of times in a regular interval - Retrofit & RxJava定期轮询后端 API 一定次数 - Retrofit & RxJava
【发布时间】:2017-07-05 08:27:57
【问题描述】:

我希望在预定义的定期间隔内对后端调用进行一定次数的轮询。如果我在循环之间收到预期的有效负载,我想退出循环并更新 UI,否则终止轮询。

以下是我进行标准 http 调用时通常执行的代码。

//Response Model from backend API
public class ApplicationStatusResponse
{
public boolean isActive;
}

//Retrofit facade  
@POST(v1/api/applicationStatus)
Single<ApplicationStatusResponse> checkApplicationStatus(@Body ApplicationStatusRequest applicationRequest);


-----

DisposableSingleObserver<ApplicationStatusResponse> disposableSingleObserver = new DisposableSingleObserver<ApplicationStatusResponse>() {
    @Override
    public void onSuccess(ApplicationStatusResponse response) {
            // Update UI Here
    }

    @Override
    public void onError(Throwable e) {

    }
};

CompositeDisposable compositeDisposable = new CompositeDisposable();

// Following call works alaways works 
DisposableSingleObserver<ApplicationStatusResponse> disposable = originationRepo.checkApplicationStatus(applicationStatusRequest)
        .observeOn(schedulerProvider.mainThread())
        .subscribeWith(disposableSingleObserver);

compositeDisposable.add(disposable);

但是我在下面的代码中有点迷失了,语法错误,当从 Flowable.interval 调用时我无法使用相同的disposableSingleObserver,并且在我需要更新 UI 的用例方面需要帮助定期状态直到时间过去或状态处于活动状态,这首先发生,如果我收到 500 的 HTTP 状态代码,我也不会终止轮询,而是重复直到满足上述条件。

 //Help Needed here  when I need polling in regular interval - I am kind of the syntax error complain from Android Studio

int INITIAL_DELAY = 0;
int POLLING_INTERVAL = 1000;
int POLL_COUNT = 8;

disposable = Flowable
            .interval(INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS)
            .map(x -> originationRepo.checkApplicationStatus(applicationStatusRequest))
            .take(POLL_COUNT) ??
            // How can I receive the response payload and update the UI

compositeDisposable.add(disposable);

提前感谢您的帮助。

【问题讨论】:

    标签: android retrofit2 rx-java2


    【解决方案1】:

    (继续MyDogTom's answer,您还可以通过抛出自定义错误/异常“短路”可观察对象)

    选项 3:

    disposable = Flowable
            .interval(INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS)
            .map(x -> originationRepo.checkApplicationStatus(applicationStatusRequest)) // .flatMap (?)
            .take(POLL_COUNT) //YES
            .doOnNext() // update UI here
            .map(response -> {
               if(!response.checkCondition()) {
                 throw new ShortCircuitException();
               }
                 return response.data();
            })
            .onErrorResumeNext(throwable -> (throwable instanceof ShortCircuitException)
                ? Observable.empty()
                : Observable.error(throwable))
    

    【讨论】:

      【解决方案2】:

      选项#1使用filter + take(1)

      disposable = Flowable
                  .interval(INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS)
                  .map(x -> originationRepo.checkApplicationStatus(applicationStatusRequest))
                  .take(POLL_COUNT) //YES
                  .doOnNext() // update UI here
                  .map(response -> ) // should stop condition. true - stop, false - continue
                  .filter(!shouldContinue)
                  .take(1)
      

      选项#2使用Subject + takeUntil

      Subject<Boolean> stopSubject = PublishSubject.create();
      disposable = Flowable
                  .interval(INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS)
                  .takeUntil(stopSubject.asObservable())
                  .map(x -> originationRepo.checkApplicationStatus(applicationStatusRequest))
                  .take(POLL_COUNT) //YES
                  .subscribe(
                      response -> {
                          //update UI
                          boolean shouldStop = ... // calculate
                          if (shouldStop) {
                              stopSubject.onNext(true);
                          }
                      }
                  ...
                   )
      

      附言。这是伪代码。我希望你能明白。

      【讨论】:

      • 感谢您的回复。不确定我是否朝着正确的方向接近,但似乎代码被重复并且过滤器pasteboard.co/GzFRbOe.png上也出现语法错误
      • 你不需要DisposableSingleObserver。在DisposableSingleObserver 中直接放置您的“更新 UI”代码。这将是您进行 UI 更新的唯一地方。在map 中放置返回true 或false 的函数。作为一般做法 - 永远不要在流中使用外部状态。阅读地图的工作原理:reactivex.io/documentation/operators/map.htmlfiler reactivex.io/documentation/operators/filter.html
      • 我的意思是“在doOnNext里面直接放你的“更新UI”代码。”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-07-22
      • 2018-06-29
      • 2015-08-15
      • 2016-09-06
      相关资源
      最近更新 更多