Как добавить результаты многих запросов AsyncHttpClient в список - PullRequest
0 голосов
/ 11 декабря 2018

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

Пока у меня есть:

//I have a private static ArrayList<String> lists that I am hoping
//to use to concatenate all responses into one list with

private static ArrayList<String> lists;

/*
 * @param bodies - an array list of the bodies I will be iterating through (as JSON strings) to add a different body to each post request
 * @param url - the url to send post request to
 */
public void makeTheCalls(ArrayList<String> bodies, String url) {
    AsyncHttpClient client = asyncHttpClient();
    for (int idx = 0; idx < bodies.size(); idx++) {
        client.preparePost(url).setBody(bodies.get(idx)).execute(new AsyncCompletionHandler<Void>() {
            @Override
            public Void onCompleted(Response response) throws exception {
                // map the response to my POJO for this particular response
                MyClass obj = objectMapper.readValue(response.getResponseBody(), MyClass.class);
                //print the ArrayList<String> i want to concat to my master list
                System.out.println(obj.getMyField());
                lists.addAll(obj.getMyfield());
                return null;
            }
        });
    }
    System.out.println(lists.size());
}

Кажется, что все мои почтовые запросы выполняются асинхронно, и даже каждый мой ответ печатается правильно.Но когда я пытаюсь использовать поле «списки» позже, например, когда я пытаюсь напечатать list.size (), оно кажется пустым.

Правильно ли используется в этом коде статическое поле, чтобы каждый поток мог редактировать один и тот же экземпляр?Происходит ли логика с массивом списков до возвращения ответов?(если это так, как я могу заставить логику откладывать до тех пор, пока все запросы не будут возвращены при сохранении асинхронных вызовов?

____________________ ОТВЕТ __________________

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

//I have a private static ArrayList<String> lists that I am hoping
//to use to concatenate all responses into one list with

private static ArrayList<String> lists;

/*
 * @param bodies - an array list of the bodies I will be iterating through (as JSON strings) to add a different body to each post request
 * @param url - the url to send post request to
 */
public void makeTheCalls(ArrayList<String> bodies, String url) {
    final CountDownLatch latch = new CountDownLatch(bodies.size());
    AsyncHttpClient client = asyncHttpClient();
    for (int idx = 0; idx < bodies.size(); idx++) {
        client.preparePost(url).setBody(bodies.get(idx)).execute(new AsyncCompletionHandler<Void>() {
            @Override
            public Void onCompleted(Response response) throws exception {
                // map the response to my POJO for this particular response
                MyClass obj = objectMapper.readValue(response.getResponseBody(), MyClass.class);
                //print the ArrayList<String> i want to concat to my master list
                System.out.println(obj.getMyField());
                lists.addAll(obj.getMyfield());
                return null;
            }
        });
    }
    latch.await();
    client.close();
    System.out.println(lists.size());
}

1 Ответ

0 голосов
/ 11 декабря 2018

Поскольку выполнение асинхронно, ваш код продолжает печатать содержимое lists до того, как обратные вызовы фактически его заполняют.Вы можете использовать CountDownLatch (см. Пример 3 здесь ), чтобы гарантировать завершение всех запросов перед печатью содержимого.

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

...