Recently I've delved into a little bit of work using an API. The API uses the Unirest http library to simplify the work of receiving from the web. Naturally, since the data is called from the API server, I tried to be efficient by using asynchronous calls to the API. My idea is structured as follows:
Therefore, I need to have all the data returned before I can start the second step. My code is as follows:
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);
How would I make it so doStuff is called only after both of the futures are finished?
wait<T> method Null safety Returns a future which will complete once all the provided futures have completed, either with their results, or with an error if any of the provided futures fail.
A ListenableFuture represents the result of an asynchronous computation: a computation that may or may not have finished producing a result yet. It's a type of Future that allows you to register callbacks to be executed once the computation is complete, or if the computation is already complete, immediately.
A Future interface provides methods to check if the computation is complete, to wait for its completion and to retrieve the results of the computation. The result is retrieved using Future's get() method when the computation has completed, and it blocks until it is completed.
In Java, Future is an interface that belongs to java. util. concurrent package. It is used to represent the result of an asynchronous computation. The interface provides the methods to check if the computation is completed or not, to wait for its completion, and to retrieve the result of the computation.
There are a few options. The code you have now calls doStuff
from the same thread where you make your requests. If you want to block until both requests have completed you could use a CountDownLatch. Something like:
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);
If you don't want to block that thread until both calls are complete, you could have each of your anonymous inner Callback classes increment an AtomicInteger. When the count is 2 you'd call doStuff
. Something like:
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);
}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With