Я не могу понять разницу между thenApply(
) и thenCompose()
.
Итак, может ли кто-нибудь предоставить допустимый вариант использования?
Из документов Java:
thenApply(Function<? super T,? extends U> fn)
Возвращает новое значение,
CompletionStage
которое при нормальном завершении этого этапа выполняется с результатом этого этапа в качестве аргумента предоставленной функции.
thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
Возвращает новое значение,
CompletionStage
которое, когда этот этап завершается нормально, выполняется с этим этапом в качестве аргумента предоставленной функции.
Я понимаю, что второй аргумент thenCompose
расширяет CompletionStage там, где thenApply
его нет.
Может ли кто-нибудь привести пример, в каком случае я должен использовать thenApply
и когда thenCompose
?
map
иflatMap
вStream
?thenApply
этоmap
иthenCompose
естьflatMap
изCompletableFuture
. Вы используете,thenCompose
чтобы избежатьCompletableFuture<CompletableFuture<..>>
.map
и,flatMap
и я понимаю вашу точку зрения.Ответы:
thenApply
используется, если у вас есть функция синхронного сопоставления.thenCompose
используется, если у вас есть функция асинхронного сопоставления (т. е. та, которая возвращает aCompletableFuture
). Затем он вернет будущее с результатом напрямую, а не вложенное будущее.источник
.thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1))
вместо.thenApplyAsync(x -> x+1)
? Синхронизация или асинхронность не имеет значения.CompletableFuture
, то это былthenCompose
бы способ сгладить структуру.thenApplyAsync
потому что это не то, что вы думаете.Я думаю, что ответ, опубликованный @Joe C, вводит в заблуждение.
Позвольте мне попытаться объяснить разницу между
thenApply
иthenCompose
на примере.Предположим, у нас есть 2 метода:
getUserInfo(int userId)
иgetUserRating(UserInfo userInfo)
:Оба типа возвращаемых методов - это
CompletableFuture
.Мы хотим
getUserInfo()
сначала вызвать , а по его завершении вызватьgetUserRating()
с результатомUserInfo
.По завершении
getUserInfo()
метода давайте попробуем обаthenApply
иthenCompose
. Разница в возвращаемых типах:thenCompose()
работает как Scala,flatMap
который выравнивает вложенные фьючерсы.thenApply()
вернули вложенные фьючерсы такими, какие они были, ноthenCompose()
сгладили вложенные,CompletableFutures
чтобы было легче связать с ним больше вызовов методов.источник
UserInfo
(тогда да) или его нужно получать отдельно, может быть, даже дорого (тогда нет).Обновленные Javadocs в Java 9, вероятно, помогут лучше понять это:
thenApply
<U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn)
thenCompose
источник
map
иflatMap
в первую очередь.thenApply()
будет просто вызыватьFunction.apply()
, иthenCompose()
это немного похоже на составление функций.thenApply
иthenCompose
являются методамиCompletableFuture
. Используйте их, когда намереваетесь сделать что-то, чтобы добитьсяCompleteableFuture
результата с помощьюFunction
.thenApply
иthenCompose
оба возвращаютCompletableFuture
как свой собственный результат. Вы можете объединить несколькоthenApply
илиthenCompose
вместе. Поставьте aFunction
для каждого вызова, результат которого будет вводом для следующегоFunction
.Предоставленному
Function
вами иногда необходимо что-то делать синхронно. Тип возврата вашегоFunction
должен быть неFuture
типом. В этом случае вам следует использоватьthenApply
.В других случаях вы можете захотеть выполнить здесь асинхронную обработку
Function
. В этом случае вам следует использоватьthenCompose
. Тип возврата вашегоFunction
должен бытьCompletionStage
. СледующийFunction
в цепочке получит результатCompletionStage
как входной, таким образом разворачивая файлCompletionStage
.Это похоже на идею Javascript
Promise
.Promise.then
может принимать функцию, которая либо возвращает значение, либоPromise
значение. Причина, по которой эти два метода имеют разные имена в Java, связана с общим стиранием .Function<? super T,? extends U> fn
иFunction<? super T,? extends CompletionStage<U>> fn
считаются одним и тем же типом среды выполнения -Function
. Таким образом,thenApply
иthenCompose
он должен быть четко назван, иначе компилятор Java будет жаловаться на идентичные сигнатуры методов. Конечным результатом является то, что JavascriptPromise.then
реализован в двух частях -thenApply
иthenCompose
- в Java.Вы можете прочитать мой другой ответ, если вас не смущает связанная функция
thenApplyAsync
.источник