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

时间:2018-12-11 20:15:17

标签: java http asynchronous post asynchttpclient

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

这似乎正在异步发出我的所有帖子请求,甚至可以正确打印我的每个回复。但是,当我稍后尝试使用“列表”字段时,例如当我尝试打印lists.size()时,它似乎仍然是空的。

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

____________________ 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());
}

1 个答案:

答案 0 :(得分:1)

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

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