The problem with the code below is that I have to wait for all three tasks to finish.
If the 1st and 2nd tasks complete in 200ms and the 3rd completes in 2s then I will have to wait 2s before I load the next three URLs.
Ideally I would send a new request as soon as each task finishes and delay the main thread somehow until the ArrayList was empty.
In simple terms I would like each completable future to run in a kind of loop that is triggered by the old task completing.
(I do this quite often in JavaScript using events)
Can anybody think how I might achieve this?
private static void httpClientExample(){
ArrayList<String> urls = new ArrayList<>(
Arrays.asList(
"https://www.bing.com/",
"https://openjdk.java.net/",
"https://openjdk.java.net/",
"https://google.com/",
"https://github.com/",
"https://stackoverflow.com/"
));
HttpClient httpClient = HttpClient.newHttpClient();
var task1 = httpClient.sendAsync(HttpRequest.newBuilder()
.uri(URI.create(urls.get(0)))
.build(), HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::uri).thenAccept(System.out::println);
var task2 = httpClient.sendAsync(HttpRequest.newBuilder()
.uri(URI.create(urls.get(1)))
.build(), HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::uri).thenAccept(System.out::println);
var task3 = httpClient.sendAsync(HttpRequest.newBuilder()
.uri(URI.create(urls.get(2)))
.build(), HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::uri).thenAccept(System.out::println);
// All tasks have to complete
var all = CompletableFuture.allOf(task1, task2, task3).join();
// Get the next 3 URLs
System.out.println("Main Thread Completed");
}