Как обнаружить, что все асинхронные операции завершены на Retrofit, как Promise в Javascript? - PullRequest
0 голосов
/ 19 октября 2019

У меня есть приложение, которое делает динамические запросы от Retrofit, и я хочу определить, все ли закончены с лучшей практикой, как я знаю, как сделать в javascript с Promise.

В Retrofit сегодня я делаювот так я получаю массив от объектов и сделаю x запрос в зависимости от размера массива.

Поэтому, когда я запускаю функцию, я выбираю размер из массива и каждый раз, когда мой Retrofit делает вызовЯ помещаю в свою переменную successCounter ++ и errorCounter ++ , когда сумма из этих 2 переменных равна размеру моего массива, так что это конец асинхронных функций.

Но я не знаю, еслиЭто хороший пример из моего кода:

 String filePath = system.getMp_user_name() + "/categorias/" + mpCategory.getImg();
                            downloadImage("category", filePath, mpCategory.getImg(),
                                    new SynService.ApiImageCallback() {
                                        public void onResponse(Boolean success, Integer requestCounter, Integer errorRequestCounter){
                                            if(success){
                                                categoryImgSuccessCounter++;
                                                Log.d(TAG, "Imagem baixada e armazenada com sucesso");
                                                if(categoryImgSuccessCounter.equals(arrayCategorySize)) {
                                                    HashMap<String, String> responseObj = new HashMap<>();
                                                    responseObj.put("success", "1");
                                                    responseObj.put("message", "Sincronização Completada com Sucesso");
                                                    callback.onResponse(responseObj);
                                                }
                                            } else {
                                                categoryImgErrorCounter++;
                                                Log.d(TAG, "Não foi possível fazer o download da imagem");
                                                HashMap<String, String> responseObj = new HashMap<>();
                                                responseObj.put("success", "0");
                                                responseObj.put("message", "Houve um erro no download das imagens e o processo parou");
                                                callback.onResponse(responseObj);
                                            }
                                            Integer total = categoryImgSuccessCounter + categoryImgErrorCounter;
                                            if(total.equals(arrayCategorySize)) {
                                                categoryImgFinished = true;
                                            }
                                        }
                                    });

Как я могу определить, когда весь запрос от Retrofit завершен без счетчика?

В javascript это просто так:

async function foo(things) {
  const results = [];
  for (const thing of things) {
    // Good: all asynchronous operations are immediately started.
    results.push(bar(thing));
  }
  // Now that all the asynchronous operations are running, here we wait until they all complete.
  return baz(await Promise.all(results));
}

1 Ответ

0 голосов
/ 19 октября 2019

Используйте Interceptor Retrofit для перехвата каждого запроса, а также увеличивайте / уменьшайте счетчик и делитесь обратным вызовом на основе этого.

Перехватчики - это мощный механизм, который может отслеживать, переписывать и повторять вызовы.

Перехватчик - как?


Если можно добавить одну зависимость, добавьте RxJava, и в ней есть достаточное количество операторов, которые полезны для многопоточности, и для ее обратного вызова.

Чтобы дождаться выполнения всех ваших запросов, используйте Retrofit2 в сочетании с RxJava2 с его функцией zip.

Zip объединяет выбросы нескольких наблюдаемых вместе через указанную функцию и испускает отдельные элементы для каждой комбинации на основе результатов этой функции

Добавьте RxJava2CallAdapterFactory в качестве адаптера вызова при создании экземпляра Retrofit:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

Теперь ваши методы обслуживания могут использовать любой из перечисленных выше типов в качестве типа возврата.

interface MyService {
  @GET("/user")
  Observable<User> getUser();
}


MyService retrofitApi = retrofit.create(MyService.class);

Используйте этот сервис для создания коллекции запросов и архивирования этих запросов.

// You need to use `Observable` type for the response.
List<Observable<?>> requests = new ArrayList<>();

// Make a collection of all requests
requests.add(retrofitApi.getUser());
requests.add(retrofitApi.getUser());
requests.add(retrofitApi.getUser());

// Zip all requests with the Function, which will receive the results.
Observable.zip(
        requests,
        new Function<Object[], Object>() {
            @Override
            public Object apply(Object[] objects) throws Exception {
                // Objects[] is an array of combined results of completed requests

                // do something with those results and emit new event
                return new Object();
            }
        })
        // After all requests had been performed the next observer will receive the Object, returned from Function
        .subscribe(
                // Will be triggered if all requests will end successfully (4xx and 5xx also are successful requests too)
                new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        //Do something on successful completion of all requests
                    }
                },

                // Will be triggered if any error during requests will happen
                new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable e) throws Exception {
                        //Do something on error completion of requests
                    }
                }
        );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...