2013-12-10 109 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); 
        } 
        } 
    });