RxAndroid Observable跳过doOnComplete()

时间:2018-01-18 12:04:22

标签: android rx-java retrofit2 rx-android

我正在调用多个Retrofit api simultanious并等待它的完成,这由Observable.zip()正确完成。现在我想实现进步。

这是我的实施..

private void preFetchData() {
    ApiInterface apiService1 = ApiClient.getWooRxClient().create(ApiInterface.class);
    ApiInterface apiService2 = ApiClient.getRxClient().create(ApiInterface.class);
    Map<String, String> map1 = new HashMap<>();
    map1.put("on_sale", "true");
    Observable<List<Product>> call1 = apiService1.getProducts1(map1)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 18;
                Log.e("Progress1", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");
            });

    Map<String, String> map2 = new HashMap<>();
    map2.put("featured", "true");
    Observable<List<Product>> call2 = apiService1.getProducts1(map2)
            .subscribeOn(Schedulers.io())
            .delaySubscription(100, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 18;
                Log.e("Progress2", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");
            });

    Map<String, String> map3 = new HashMap<>();
    map3.put("page", "1");
    map3.put("sort", "rating");
    map3.put("per_page", "10");
    Observable<List<Product>> call3 = apiService2.getCustomProducts1(map3)
            .subscribeOn(Schedulers.io())
            .delaySubscription(200, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 18;
                Log.e("Progress3", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");
            });

    Map<String, String> map4 = new HashMap<>();
    map4.put("page", "1");
    map4.put("sort", "popularity");
    map4.put("per_page", "10");
    Observable<List<Product>> call4 = apiService2.getCustomProducts1(map4)
            .subscribeOn(Schedulers.io())
            .delaySubscription(300, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 18;
                Log.e("Progress4", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");
            });

    Observable<ResponseBody> call5 = apiService2.getCurrencySymbol()
            .subscribeOn(Schedulers.io())
            .delaySubscription(400, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 10;
                Log.e("Progress5", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");
            });

    Observable<List<Category>> call6 = apiService1.getAllCategories()
            .subscribeOn(Schedulers.io())
            .delaySubscription(500, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnComplete(() -> {
                progress += 18;
                Log.e("Progress6", progress + "");
                mProgressBar.setProgress(progress);
                mProgressBar.setProgressText(progress + "%");

            });

    Observable<CombinedHomePage> combined = Observable.zip(call1, call2, call3, call4, call5, call6, CombinedHomePage::new);
    disposable = combined.subscribe(this::successHomePage, this::throwableError);
}

private void successHomePage(CombinedHomePage o) {
    Log.e("Response", "SUCCESS " + o.featuredProductList.size());
    Log.e("Response", "SUCCESS " + o.saleProductList.size());
    Log.e("Response", "SUCCESS " + o.topRatedProductList.size());
    Log.e("Response", "SUCCESS " + o.topSellerProductList.size());
    Log.e("Response", "SUCCESS " + o.CURRENCY);
    Log.e("Response", "SUCCESS " + o.categoryList.size());
}

private void throwableError(Throwable t) {
    Log.e("Response", "Fail");
}

这是Logcat

  

首次运行

E/Progress5: 10.0
E/Progress2: 28.0
E/Progress1: 46.0
E/Progress6: 64.0
E/Progress3: 82.0
E/Response: Featured List Size 5
E/Response: Sale List Size 7
E/Response: Rated List Size 10
E/Response: Seller List Size 10
E/Response: Currency $
E/Response: Category List Size 9
  

第二次运行

E/Progress5: 10.0
E/Progress2: 28.0
E/Progress1: 46.0
E/Progress6: 64.0
E/Progress4: 82.0
E/Response: Featured List Size 5
E/Response: Sale List Size 7
E/Response: Rated List Size 10
E/Response: Seller List Size 10
E/Response: Currency $
E/Response: Category List Size 9

在第一次运行时,Progess 4跳过,在第二次运行时Progess 3跳过(所有Api正确完成)。

任何想法为什么会这样?

任何帮助都是适当的

1 个答案:

答案 0 :(得分:2)

javadoc

中对此进行了描述
  

操作员按照指定的顺序订阅其来源,并在处置其他来源时,如果其中一个来源比其他来源短,则急切地完成。因此,有可能其他源永远不能运行完成(因此不会调用doOnComplete())。如果源的长度完全相同,也会发生这种情况;如果源A完成并且B已经消耗并且即将完成,则操作员检测到A将不会发送更多值并且它将立即处置B.例如:

     

zip(Arrays.asList(range(1, 5).doOnComplete(action1), range(6, 5).doOnComplete(action2)), (a) -> a)

     

将调用action1但不会调用action2。   要解决此终止属性,请使用doOnDispose(Action)或使用using()在完成或dispose()调用时进行清理。