如何从回调获得番石榴ListenableFuture?

时间:2017-12-24 08:23:51

标签: java guava apache-httpclient-4.x

我想使用apache async http客户端进行异步http调用,以便为每个线程运行多个调用。

此处列出了代码:https://hc.apache.org/httpcomponents-asyncclient-dev/quickstart.html

CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();

// Start the client
httpclient.start();

// One most likely would want to use a callback for operation result
final CountDownLatch latch1 = new CountDownLatch(1);
final HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback<HttpResponse>() {

    public void completed(final HttpResponse response2) {
        latch1.countDown();
        System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
    }

    public void failed(final Exception ex) {
        latch1.countDown();
        System.out.println(request2.getRequestLine() + "->" + ex);
    }

    public void cancelled() {
        latch1.countDown();
        System.out.println(request2.getRequestLine() + " cancelled");
    }

});
latch1.await();

我最后一次在nodejs中编程,并对promise方法非常满意。我找到的最近的项目是来自GUAVA的ListenableFuture。 (我不能使用Java 8)。问题是如何将回调方法转换为ListenableFuture。

在nodejs中这很容易,因为在回调中我可以调用resolve函数。我不知道如何在Java中这样做,我没有在谷歌中找到如何做到这一点。

2 个答案:

答案 0 :(得分:1)

如API所述,execute方法返回Future。由于它与回调链接,因此它应该是一个ListenableFuture

ListenableFuture<HttpResponse> future = (ListenableFuture<HttpResponse>) httpclient.execute(...);

应该做的伎俩(在回调中,你不能这样做)。从技术上讲,你甚至不需要投射Future,因为正常的Future应该足以满足你的用例,因为你不需要更多的回调,如果我有你的话。

如果你想彻底摆脱回调(什么是不那么混乱的解决方案)你需要使用HttpClient的另一个实现,但它需要重写代码。

在回调中,你无法获得未来,反正你也不需要它,因为未来的结果是回调的参数。

答案 1 :(得分:0)

以下帖子非常有用:Turning a listener into a future in java 我想做的是:

// One most likely would want to use a callback for operation result
final SettableFuture<String> future = SettableFuture.create();
final HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback<HttpResponse>() {

    public void completed(final HttpResponse response2) {

        future.set(request2.getRequestLine() + "->" + response2.getStatusLine());
    }

    public void failed(final Exception ex) {
        future.set(request2.getRequestLine() + "->" + ex);
    }

    public void cancelled() {

        future.set(request2.getRequestLine() + " cancelled");
    }

});