2013-12-10 84 views
8

最近我已经钻研使用API​​的一些工作。该API使用Unirest http库来简化从网络接收的工作。当然,由于数据是从API服务器调用的,我试图通过对API进行异步调用来提高效率。我的想法的结构如下:等待多个期货的回调

  1. 通过返回期货从数据

因此聚集

  • 显示数据+附加信息的结果创建数据的数组,我需要的所有数据在我开始第二步之前返回。我的代码如下:

    Future < HttpResponse <JsonNode> > future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback <JsonNode>() { 
        public void failed(UnirestException e) { 
         System.out.println("The request has failed"); 
        } 
        public void completed(HttpResponse <JsonNode> response) { 
         System.out.println(response.getBody().toString()); 
         responses.put(response); 
        } 
        public void cancelled() { 
         System.out.println("The request has been cancelled"); 
        } 
    }); 
    Future < HttpResponse <JsonNode> > future2 = Unirest.get("https://example.com/api").asJsonAsync(new Callback <JsonNode>() { 
        public void failed(UnirestException e) { 
         System.out.println("The request has failed"); 
        } 
        public void completed(HttpResponse <JsonNode> response) { 
         System.out.println(response.getBody().toString()); 
         responses.put(response); 
        } 
        public void cancelled() { 
         System.out.println("The request has been cancelled"); 
        } 
    }); 
    doStuff(responses); 
    

    我该如何做到这一点,所以doStuff只有在两个期货完成后才会被调用?

  • +0

    可能想看看'ExecutorCompletionService'但允许您在任何响应完成做的东西。 – Gray

    +1

    http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish – goat

    回答

    7

    有几个选项。您现在使用的代码在您提出请求的同一个线程中调用doStuff。如果你想阻塞,直到两个请求都完成,你可以使用CountDownLatch。喜欢的东西:

    CountDownLatch responseWaiter = new CountDownLatch(2); 
    
    Future <HttpResponse<JsonNode>> future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback<JsonNode>() { 
        public void completed(HttpResponse<JsonNode> response) { 
        responses.put(response); 
        responseWaiter.countDown(); 
        } 
        ... 
    }); 
    
    // Similar code for the other get call 
    ... 
    
    responseWaiter.await(); 
    doStuff(responses); 
    

    如果您不希望阻止该线程直到两个电话都齐全,你可以有你的每一个匿名内部回调类的增加的的AtomicInteger。当计数是2时,您可以拨打doStuff。喜欢的东西:

    AtomicInteger numCompleted = new AtomicInteger(); 
    
    Future <HttpResponse<JsonNode>> future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback<JsonNode>() { 
        public void completed(HttpResponse<JsonNode> response) { 
        responses.put(response); 
        int numDone = numCompleted.incrementAndGet(); 
        if (numDone == 2) { 
         doStuff(responses); 
        } 
        } 
    });