Проект "Реактор". Mono.map () против Mono.flatMap ()

В чем принципиальная разница между ними с точки зрения Mono? Из документации я прочитал, что flatMap действует асинхронно и map синхронно. Но для меня это не имеет смысла, потому что Mono - это все о параллелизме, и этот момент непонятен. Может кто-нибудь более понятно перефразировать?

Затем в документации для flatMap указано (https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#flatMap-java.util.function.Function-):

Transform the item emitted by this Mono asynchronously, returning the 
value emitted by another Mono (possibly changing the value type).

Какой еще Моно там имеется в виду?


person Roman T    schedule 07.06.2019    source источник


Ответы (1)


Mono#flatMap принимает Function, который преобразует значение в другое Mono. Этот Mono может представлять некоторую асинхронную обработку, например HTTP-запрос.

С другой стороны, Mono#map принимает Function, который преобразует значение типа T в другое значение типа R. Таким образом, это преобразование выполняется императивно и синхронно (например, преобразование String в экземпляр URL).

Другая тонкость с flatMap заключается в том, что оператор подписывается на сгенерированный Mono, в отличие от того, что произошло бы, если бы вы передали тот же Function map.

person Simon Baslé    schedule 08.06.2019
comment
Означает ли это, что если я использую Mono#map, преобразование будет применено немедленно, не дожидаясь подписки? А с Mono#flatMap он будет выполнен первым после того, как появится подписчик? Я действительно не понимаю, зачем мне создавать новый Mono с помощью flatMap. - person Roman T; 14.06.2019
comment
Другой вопрос, я прав, что Mono#map, #flatMap не имеет прямого отношения к #map и #flatMap java.util.stream.Stream? - person Roman T; 14.06.2019
comment
они относятся к Stream методам! Stream#flatMap собирает значения из внутренних потоков и выравнивает их в результирующем Stream. В реактивных типах собирающая часть подразумевает подписку. Единственная разница в том, что в Mono#flatMap есть только одно значение для сглаживания, поэтому более близким методом будет Mono#flatMapMany (что приводит к Flux) - person Simon Baslé; 28.06.2019
comment
Суть в том, что ваша функция преобразования внутри Mono # flatmap должна возвращать Publisher (Mono) для оператора flatMap, на который можно подписаться. В этом синтаксическая разница. Другая основная (более важная) разница заключается в том, что если ваша функция преобразования включает в себя блокирующие вызовы, вам лучше использовать flatMap, чтобы издатель, который он возвращает, мог продолжить асинхронную обработку под капотом, делая ваш конвейер непрерывным асинхронным. С другой стороны, карта просто заблокирует поток, тем самым влияя на асинхронное поведение конвейера. - person Vivek Sethi; 10.12.2019