Não consigo entender a diferença entre thenApply(
) e thenCompose()
.
Então, alguém poderia fornecer um caso de uso válido?
Dos documentos Java:
thenApply(Function<? super T,? extends U> fn)
Retorna um novo
CompletionStage
que, quando este estágio é concluído normalmente, é executado com o resultado desse estágio como o argumento para a função fornecida.
thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
Retorna um novo
CompletionStage
que, quando este estágio é concluído normalmente, é executado com este estágio como o argumento da função fornecida.
Eu entendo que o segundo argumento de thenCompose
estende o CompletionStage onde thenApply
não.
Alguém poderia dar um exemplo em que caso devo usar thenApply
e quando thenCompose
?
map
eflatMap
emStream
?thenApply
é omap
ethenCompose
é oflatMap
deCompletableFuture
. Você usathenCompose
para evitar terCompletableFuture<CompletableFuture<..>>
.map
eflatMap
e entendi. Obrigado novamente :)Respostas:
thenApply
é usado se você tiver uma função de mapeamento síncrono.thenCompose
é usado se você tiver uma função de mapeamento assíncrona (ou seja, uma que retorna aCompletableFuture
). Em seguida, ele retornará um futuro com o resultado diretamente, em vez de um futuro aninhado.fonte
.thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1))
vez de.thenApplyAsync(x -> x+1)
? Ser síncrono ou assíncrono não é a diferença relevante.CompletableFuture
, então este seriathenCompose
o caminho para nivelar a estrutura.thenApplyAsync
porque não é o que você pensa que é.Acho que a resposta postada por @Joe C é enganosa.
Deixe-me tentar explicar a diferença entre
thenApply
ethenCompose
com um exemplo.Vamos supor que temos 2 métodos:
getUserInfo(int userId)
egetUserRating(UserInfo userInfo)
:Ambos os tipos de retorno de método são
CompletableFuture
.Queremos chamar
getUserInfo()
primeiro e, ao concluir, chamargetUserRating()
com o resultadoUserInfo
.Na conclusão do
getUserInfo()
método, vamos tentar ambosthenApply
ethenCompose
. A diferença está nos tipos de retorno:thenCompose()
funciona como Scala,flatMap
que nivela futuros aninhados.thenApply()
retornou os futuros aninhados como estavam, masthenCompose()
achatou os aninhadosCompletableFutures
para que seja mais fácil encadear mais chamadas de método para ele.fonte
UserInfo
(então sim) ou se deve ser obtida separadamente, talvez até custosa (então não).Os Javadocs atualizados em Java 9 provavelmente ajudarão a entendê-lo melhor:
thenApply
<U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn)
thenCompose
fonte
map
eflatMap
em primeiro lugar.thenApply()
simplesmente chamaráFunction.apply()
, ethenCompose()
é um pouco semelhante às funções de composição.thenApply
ethenCompose
são métodos deCompletableFuture
. Use-os quando quiser fazer algo para obterCompleteableFuture
o resultado de aFunction
.thenApply
ethenCompose
ambos retornam aCompletableFuture
como seu próprio resultado. Você pode encadear váriosthenApply
outhenCompose
juntos. Forneça umFunction
para cada chamada, cujo resultado será a entrada para a próximaFunction
.O que
Function
você forneceu às vezes precisa fazer algo de forma síncrona. O tipo de retorno de seuFunction
deve ser um nãoFuture
tipo. Neste caso, você deve usarthenApply
.Outras vezes, você pode querer fazer processamento assíncrono neste
Function
. Nesse caso, você deve usarthenCompose
. O tipo de retorno de seuFunction
deve ser aCompletionStage
. O próximoFunction
na cadeia obterá o resultado dissoCompletionStage
como entrada, desembrulhando oCompletionStage
.Esta é uma ideia semelhante à do Javascript
Promise
.Promise.then
pode aceitar uma função que retorna um valor ouPromise
de um valor. A razão pela qual esses dois métodos têm nomes diferentes em Java é devido ao apagamento genérico .Function<? super T,? extends U> fn
eFunction<? super T,? extends CompletionStage<U>> fn
são considerados o mesmo tipo de tempo de execução -Function
. Portanto,thenApply
ethenCompose
deve ser nomeado de forma distinta, ou o compilador Java reclamaria sobre assinaturas de método idênticas. O resultado final é que o JavascriptPromise.then
é implementado em duas partes -thenApply
ethenCompose
- em Java.Você pode ler minha outra resposta se também estiver confuso sobre uma função relacionada
thenApplyAsync
.fonte