Nie mogę zrozumieć różnicy między thenApply(
) a thenCompose()
.
Czy więc ktoś mógłby podać prawidłowy przypadek użycia?
Z dokumentacji Java:
thenApply(Function<? super T,? extends U> fn)
Zwraca nową wartość,
CompletionStage
która po normalnym zakończeniu tego etapu jest wykonywana z wynikiem tego etapu jako argumentem dostarczonej funkcji.
thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
Zwraca nową wartość,
CompletionStage
która po normalnym zakończeniu tego etapu jest wykonywana z tym etapem jako argumentem dostarczonej funkcji.
Rozumiem, że drugi argument thenCompose
rozszerza CompletionStage, gdzie thenApply
nie.
Czy ktoś mógłby podać przykład, w którym przypadku muszę użyć thenApply
i kiedy thenCompose
?
map
iflatMap
wStream
?thenApply
jestmap
ithenCompose
jestflatMap
zCompletableFuture
. Używasz,thenCompose
aby uniknąć posiadaniaCompletableFuture<CompletableFuture<..>>
.map
iflatMap
i rozumiem twój punkt widzenia.Odpowiedzi:
thenApply
jest używany, jeśli masz synchroniczną funkcję mapowania.thenCompose
jest używany, jeśli masz asynchroniczną funkcję mapującą (tj. taką, która zwraca aCompletableFuture
). Następnie zwróci przyszłość bezpośrednio z wynikiem, a nie zagnieżdżoną przyszłość.źródło
.thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1))
zamiast.thenApplyAsync(x -> x+1)
? Bycie synchronicznym lub asynchronicznym nie jest istotną różnicą.CompletableFuture
, to byłbythenCompose
to sposób na spłaszczenie struktury.thenApplyAsync
ponieważ nie jest to, o czym myślisz.Myślę, że odpowiedź zamieszczona przez @Joe C jest myląca.
Spróbuję wyjaśnić różnicę między
thenApply
ithenCompose
na przykładzie.Załóżmy, że mamy 2 metody:
getUserInfo(int userId)
igetUserRating(UserInfo userInfo)
:Oba typy zwracanych metod to
CompletableFuture
.Chcemy
getUserInfo()
najpierw wywołać , a po jego zakończeniu zadzwonićgetUserRating()
z wynikiemUserInfo
.Po zakończeniu
getUserInfo()
metody wypróbujmy obathenApply
ithenCompose
. Różnica polega na typach zwracanych:thenCompose()
działa jak Scala,flatMap
która spłaszcza zagnieżdżone futures.thenApply()
zwrócił zagnieżdżone futures bez zmian, alethenCompose()
spłaszczył zagnieżdżone,CompletableFutures
aby łatwiej było połączyć z nim więcej wywołań metod.źródło
UserInfo
(wtedy tak), czy też musi być uzyskana oddzielnie, może nawet kosztowna (wtedy nie).Zaktualizowany Javadocs w Javie 9 prawdopodobnie pomoże lepiej to zrozumieć:
następnie zastosuj
<U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn)
następnie utwórz
źródło
map
iflatMap
przede wszystkim.thenApply()
że po prostu zadzwoniFunction.apply()
ithenCompose()
jest trochę podobny do tworzenia funkcji.thenApply
ithenCompose
są metodamiCompletableFuture
. Używaj ich, jeśli zamierzasz zrobić coś, aby uzyskaćCompleteableFuture
wynik za pomocąFunction
.thenApply
ithenCompose
oba zwracająCompletableFuture
jako własny wynik. Możesz łączyć wielethenApply
lubthenCompose
razem. Podaj aFunction
do każdego wywołania, którego wynik będzie wejściem do następnegoFunction
.To,
Function
co dostarczyłeś, czasami musi zrobić coś synchronicznie. Zwracany typ nieFunction
powinien byćFuture
typem. W takim przypadku powinieneś użyćthenApply
.Innym razem możesz chcieć wykonać asynchroniczne przetwarzanie w tym
Function
. W takim przypadku powinieneś użyćthenCompose
. Typ zwrotuFunction
powinien być aCompletionStage
. NastępnyFunction
w łańcuchu otrzyma wynik tegoCompletionStage
jako dane wejściowe, tym samym rozpakowując plikCompletionStage
.To jest podobny pomysł do Javascript
Promise
.Promise.then
może akceptować funkcję, która zwraca wartość lub aPromise
z wartości. Powodem, dla którego te dwie metody mają różne nazwy w Javie, jest ogólne wymazywanie .Function<? super T,? extends U> fn
iFunction<? super T,? extends CompletionStage<U>> fn
są uważane za ten sam typ środowiska wykonawczego -Function
. DlategothenApply
ithenCompose
musi być wyraźnie nazwany, inaczej kompilator Java narzekałby na identyczne sygnatury metod. Efektem końcowym jest to, że JavaScriptPromise.then
jest zaimplementowany w dwóch częściach -thenApply
ithenCompose
- w Javie.Możesz przeczytać moją drugą odpowiedź, jeśli nie masz pewności co do powiązanej funkcji
thenApplyAsync
.źródło