Retrofit & RxJava: сделать несколько независимых запросов и определить, когда они все завершены - PullRequest
1 голос
/ 12 марта 2019

После запуска моего приложения мне нужно загрузить несколько независимых данных и проверить, все ли они хорошо загружены.

Что я делаю: сначала аутентифицируюсь, затем отправляю все запросы на загрузку данных. Каждый вызов независим, он просто используется для обновления локальной базы данных. Звонок работает хорошо.

Но как мне узнать, что все запросы выполнены?

public static void loadData() {

        LoginService loginService =
                RetrofitHelper.createService(LoginService.class);

        user = new User(ApplicationCore.syncLogin, ApplicationCore.syncPassword);

        loginService.login(user)
                .doOnNext(accessToken -> storeCredentials(accessToken))
                .doOnNext(a -> processData1())
                .doOnNext(a -> processData2())
                .doOnNext(a -> processData3())
                .doOnNext(a -> processData4())
                .subscribeOn(Schedulers.io())
                .onErrorResumeNext(Observable.empty())
                .subscribe(a -> Log.d("XXX","*********** END *********"));
    }

private static DisposableSingleObserver processData1 () {


        return RetrofitHelper.createService(Data1Service.class, true, authType, authToken).fetchAll(ApplicationCore.appVersionNum)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableSingleObserver<List<Data1>>() {
                    @Override
                    public void onSuccess(List<Data1> dataList) {
                        if (Data1DB.updateData(new ArrayList<>(dataList)) ) {  // success

                        } else {

                            Log.d(TAG,"Error on processData1");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG,"Error on processData1",e);
                    }
                });
    }

В своем журнале я вижу, что «*********** END *********» отображается сразу после сетевых вызовов до получения данных.

Я хотел бы иметь возможность наблюдать, когда обрабатываются последние данные.

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

Вот как это реализовано сейчас. Каждый "processData1 ()" выполняется либо последовательно, если в каждой функции processDataX нет "subscribeOn", либо параллельно, если добавлено "subscribeOn".

А потом, когда все закончится, подписка будет выполнена.

          public static void loadRefMatrix() {

                LoginService loginService =
                        RetrofitHelper.createService(LoginService.class);

                user = new User(ApplicationCore.syncLogin, ApplicationCore.syncPassword);
        loginService.login(user)
                .doOnNext(accessToken -> storeCredentials(accessToken))
                .flatMapCompletable(a -> Completable.mergeArray(
                        processData1(),
                        processData2(),
                        processData3(),
                        processData4(),
                        processData5(),
                        processData6(),
                        processData7()
                        )
                )         
    .subscribeOn(Schedulers.io())
                .subscribe(new DisposableCompletableObserver() {
    @Override
    public void onComplete() {
        Log.d(TAG, "*********** END *********");
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "*********** ERROR *********");
    }
})

 )
                ;
            }

         private static Completable processData1 () {

                return RetrofitHelper.createService(Data1Service.class, true, authType, authToken).fetchAll(ApplicationCore.appVersionNum)
                      .map(data -> {
                                if (Data1DB.updatData(new ArrayList<>(data)) ) {  // success

                                } else {
                                    Log.d(TAG,"Error on processAcuityMatrix do data");
                                }
                                return true;
                            })
     .subscribeOn(Schedulers.io())  // <-- this to process in parallele                   
    .toCompletable();
        }
0 голосов
/ 13 марта 2019

Есть несколько доступных вариантов, но, пожалуйста, рассмотрите этот вариант (псевдокод):

    loginService.login(user)
            .doOnNext(accessToken -> storeCredentials(accessToken))
            .flatMapCompletable(a -> Completable.mergeArray(
                     fetchAll1(...)
                         .map(data->...Data1DB.updateData...)
                         .toCompletable(),
                     fetchAll2(...)
                     ...
                 )
             )
             .subscribe(...)
...