2013-12-10 11 views
8

हाल ही में मैंने एक एपीआई का उपयोग करके थोड़ा सा काम किया है। एपीआई वेब से प्राप्त करने के काम को सरल बनाने के लिए यूनिरेस्ट http लाइब्रेरी का उपयोग करता है। स्वाभाविक रूप से, चूंकि एपीआई सर्वर से डेटा कहा जाता है, इसलिए मैंने एपीआई को एसिंक्रोनस कॉल का उपयोग करके कुशल होने की कोशिश की। मेरा विचार इस प्रकार संरचित है:एकाधिक वायदा के लिए कॉलबैक की प्रतीक्षा

  1. वायदा
  2. प्रदर्शन डेटा + अतिरिक्त जानकारी डेटा

इसलिए से इकट्ठा के परिणाम वापस लौट कर डेटा की सरणी बनाएँ, मैं सभी डेटा की आवश्यकता है दूसरा कदम शुरू करने से पहले वापस लौटा।

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

'एक्जिक्यूटर कॉम्प्लिशन सेवा' पर नज़र डालना चाहता है, लेकिन यदि कोई प्रतिक्रिया समाप्त हो जाती है तो इससे आपको सामान करने की अनुमति मिलती है। – 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); 
    } 
    } 
}); 
संबंधित मुद्दे