当我请求相同的url时,如何在retrofix2.0(rxandroid)中取消请求

时间:2017-06-12 05:54:55

标签: android rx-java retrofit2 rx-android rx-java2

我想在用户点击按钮时调用请求。但是当第一次请求没有响应时,用户想要更改参数并使用相同的URL调用新请求。

问题 如何取消第一个请求并使用相同的URL调用新请求。

 ServiceFactory
            .createService()
            .getSomething(page)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DefaultObserver<SomthingResponse>() {
                @Override
                public void onNext(@NonNull SomthingResponse response) {
                    showSomthing()
                    hideProgressDialog();

                }

                @Override
                public void onError(@NonNull Throwable e) {
                    hideProgressDialog();
                    showErrorMessage(e.getMessage());
                }

                @Override
                public void onComplete() {

                }
            });

当用户点击按钮用户将页面参数发送到查询字符串但此请求尚未完成。用户将更改为页面参数并发送新请求。我想取消第一个请求。

三江源

2 个答案:

答案 0 :(得分:5)

问题的回答是switchMap()运营商:

public static class User {} // Dummy server response

public Observable<Object> getButtonClicks() {
    return RxView.clicks(findViewById(R.id.button)); // (1)
}

public Single<User> getUserFromApi() {
    return Single.just(new User()) // (2)
            .delay(5, TimeUnit.SECONDS);
}

public void fun() {
    getButtonClicks()
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(Schedulers.io())
            .switchMap(__ -> getUserFromApi().toObservable()) // (3)
            .observeOn(AndroidSchedulers.mainThread()) // (4)
            .subscribeWith(new DisposableObserver<User>() {
                @Override public void onNext(@NonNull User user) {
                    Log.d("fun", "onNext");
                }

                @Override public void onError(@NonNull Throwable e) {
                    Log.d("fun", "onError");
                }

                @Override public void onComplete() {
                    Log.d("fun", "onComplete");
                }
            });
}

这里会发生什么:

  1. 使用库RxBinding来获取UI事件的反应式侦听器。这个observable会在每次单击按钮时发出Object
  2. Dummy API Observable。响应延迟以模仿真实的API。
  3. 切换并映射从单击observable到API observable。如果在执行API调用期间发出新的单击对象,则取消旧调用并执行新调用。 switchMap() operator marble
  4. 您可能希望观察MainThread
  5. 中的更改

答案 1 :(得分:1)

您可以使用主题和去抖动

http://reactivex.io/documentation/operators/debounce.html

https://github.com/kaskasi/TraktTVSample/blob/master/app/src/main/java/de/fluchtwege/movielist/viewmodel/MovieListViewModel.java

您可以查看此示例,它解决了类似的问题。当用户输入查询时,仅当用户停止编辑1秒时才启动请求,这样才会显示上一个请求的结果:

requestsAPI.queryMovies(query, pagesLoaded)

            .observeOn(schedulerMain)

            .debounce(1000, TimeUnit.MILLISECONDS)

            .subscribe(new Subscriber<List<MovieQuery>>() {

                @Override

                public void onCompleted() {

                }


                @Override

                public void onError(Throwable e) {

                }


                @Override

                public void onNext(List<MovieQuery> movieQueries) {

                    onMoviesLoaded(filterMoviesFromSearchResults(movieQueries));

                }

});