如何将许多 AsyncHttpClient 请求的结果添加到列表中

How to add results of many AsyncHttpClient requests to a list

我正在尝试使用 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());
}

这似乎是在异步发出我的所有 post 请求,它甚至正确地打印了我的每个响应。但是当我稍后尝试使用 'lists' 字段时,比如当我尝试打印 lists.size() 时,它似乎仍然是空的。

此代码是否正确使用静态字段以允许每个线程编辑同一实例? 'lists' 数组的逻辑是在响应返回之前发生的吗? (如果是这样,我怎样才能让逻辑延迟到所有请求都返回,同时保持调用异步?

____________________ANSWER__________________

应用程序正在发出所有异步请求,然后在响应返回之前继续。使用 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());
}

由于执行是异步的,您的代码会在回调实际填充它之前继续打印 lists 的内容。您可以使用 CountDownLatch (see example 3 here) 来确保在打印内容之前所有请求都已结束。

此外,我还会修改代码以确保 lists 变量是线程安全的。