Żądania asynchroniczne
sendAsync i CompletableFuture
Żądania asynchroniczne to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Żądania asynchroniczne
Blokowanie przy każdym wywołaniu HTTP marnuje wątki. Klient HTTP z JDK udostępnia metodę sendAsync, która natychmiast zwraca obiekt CompletableFuture, a pracę wykonuje w executorze działającym w tle.
Pozwala to uruchamiać wiele żądań jednocześnie i łączyć ich wyniki bez ręcznego zarządzania wątkami.
send a sendAsync
Sygnatury różnią się typem zwracanej wartości:
- send zwraca
HttpResponse<T>i blokuje, deklarując wyjątkiIOExceptionorazInterruptedException. - sendAsync zwraca
CompletableFuture<HttpResponse<T>>i nigdy nie blokuje; błędy są przekazywane przez obiekt future.
Podstawowe wywołanie sendAsync
Metoda sendAsync przyjmuje to samo żądanie i obiekt BodyHandler co metoda send. Zwrócony obiekt future zostaje ukończony, gdy odpowiedź jest gotowa.
import java.net.URI;
import java.net.http.*;
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
CompletableFuture<HttpResponse<String>> future =
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Request sent, future created");
}
}Przekształcanie za pomocą thenApply
Metody thenApply należy użyć do przekształcenia wyniku po jego nadejściu — na przykład do wyodrębnienia treści z odpowiedzi.
Przekształcenie wykonuje się synchronicznie na wątku, który ukończył poprzedni etap.
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future =
CompletableFuture.completedFuture("OK 200")
.thenApply(body -> "Length=" + body.length());
System.out.println(future.get());
}
}Przetwarzanie za pomocą thenAccept
Jeśli potrzebny jest tylko efekt uboczny, a nie wartość zwracana, należy użyć metody thenAccept. Przyjmuje ona obiekt Consumer i zwraca obiekt CompletableFuture<Void>.
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<Void> done =
CompletableFuture.completedFuture("payload")
.thenAccept(b -> System.out.println("Received: " + b));
done.get();
}
}Blokowanie za pomocą join
Aby zaczekać na wynik asynchroniczny w metodzie main, należy wywołać metodę join() (bez kontroli wyjątków) lub get() (z kontrolą wyjątków). W rzeczywistym serwerze zamiast blokowania należy łączyć kolejne etapy.
Metoda join() opakowuje błędy w niekontrolowany wyjątek CompletionException.
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<Integer> f =
CompletableFuture.supplyAsync(() -> 21).thenApply(n -> n * 2);
int result = f.join();
System.out.println("Result: " + result);
}
}Obsługa błędów za pomocą exceptionally
Metoda exceptionally udostępnia wartość zastępczą, gdy etap zakończy się błędem, umożliwiając wznowienie przetwarzania.
W ten sposób asynchroniczny przepływ HTTP nie kończy się z powodu błędu sieci.
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<String> f = CompletableFuture
.<String>supplyAsync(() -> { throw new RuntimeException("boom"); })
.exceptionally(ex -> "fallback: " + ex.getMessage());
System.out.println(f.join());
}
}Łączenie dwóch żądań
Metoda thenCombine czeka na dwa niezależne obiekty future i łączy ich wyniki. W przypadku asynchronicznego HTTP pozwala pobrać równolegle dane z dwóch endpointów i połączyć ich treści.
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "World");
String combined = a.thenCombine(b, (x, y) -> x + " " + y).join();
System.out.println(combined);
}
}Uruchamianie wielu żądań równolegle
Aby uruchomić serię żądań, należy zebrać każdy obiekt future na liście, a następnie użyć metody CompletableFuture.allOf(...), aby zaczekać na wszystkie żądania.
Metoda allOf zwraca obiekt CompletableFuture<Void>; poszczególne wyniki należy odczytać później.
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
List<CompletableFuture<Integer>> futures = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
int n = i;
futures.add(CompletableFuture.supplyAsync(() -> n * n));
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
for (var f : futures) System.out.println(f.join());
}
}Podsumowanie wzorca asynchronicznego
Typowy asynchroniczny przepływ HTTP wygląda następująco:
client.sendAsync(req, BodyHandlers.ofString()).thenApply(HttpResponse::body)w celu pobrania treści.thenAccept(System.out::println)w celu jej przetworzenia.exceptionally(ex -> ...)w celu odzyskania działania po błędzie
Żaden wątek nie jest blokowany w oczekiwaniu na sieć.
Kiedy wybrać tryb asynchroniczny
Należy wybrać sendAsync, gdy wykonywanych jest wiele współbieżnych wywołań, gdy żądania są rozsyłane do kilku usług lub gdy kod działa wewnątrz reaktywnego/nieblokującego serwera. Metoda send sprawdzi się w przypadku prostych skryptów i jednorazowych wywołań, w których blokowanie nie stanowi problemu.
Szybki test
Proszę sprawdzić zrozumienie zasad działania żądań asynchronicznych.
Podsumowanie
Opanowano wykonywanie nieblokujących wywołań HTTP:
- sendAsync zwraca obiekt
CompletableFuturezamiast blokować. - thenApply / thenAccept przekształcają i przetwarzają wynik.
- exceptionally dostarcza wartość zastępczą w razie błędu.
- thenCombine łączy dwa równoległe wywołania, a allOf czeka na całą serię żądań.
- Asynchroniczność sprawdza się w serwerach o dużej współbieżności i reaktywnych, natomiast synchroniczność — w prostych skryptach.
Często zadawane pytania
Czy lekcja „Żądania asynchroniczne” jest bezpłatna?
Tak — pełny tekst „Żądania asynchroniczne” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Żądania asynchroniczne”?
sendAsync i CompletableFuture Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Żądania asynchroniczne”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- java.net.http.HttpClient
- Żądania asynchroniczne
- Treści żądań i nagłówki
- Obsługa odpowiedzi