Ответ
Project Reactor — это реактивная библиотека для JVM, реализующая спецификацию Reactive Streams. Она предоставляет неблокирующую модель программирования для асинхронных потоков данных.
Основные абстракции:
Mono<T>— представляет асинхронный результат 0 или 1 элемента.Flux<T>— представляет асинхронную последовательность из 0..N элементов.
Пример создания и обработки потока:
Flux.just("Apple", "Banana", "Cherry")
.filter(fruit -> fruit.length() > 5)
.map(String::toUpperCase)
.doOnNext(System.out::println)
.subscribe(); // Подписка активирует поток
Ключевые особенности:
- Ленивость (Lazy): Вычисления начинаются только после вызова
subscribe(). - Богатый набор операторов:
map,filter,flatMap,zip,merge,concatдля трансформации и комбинирования потоков. - Обработка ошибок: Специальные операторы
onErrorResume,onErrorReturn,doOnError. - Расписание (Schedulers): Контроль над потоком выполнения (
Schedulers.parallel(),subscribeOn,publishOn). - Backpressure: Механизм, позволяющий подписчику контролировать скорость получения данных от издателя.
Применение: Используется в стеке Spring WebFlux для создания реактивных REST API, с реактивными драйверами баз данных (R2DBC), и клиентами (WebClient, реактивный Kafka).
Ответ 18+ 🔞
Ну, слушай, смотри, вот есть у нас эта штука — Project Reactor. Это, блядь, такая библиотека для JVM, которая делает вид, что она очень умная и реактивная. По сути, она реализует какую-то там спецификацию Reactive Streams, но тебе, наверное, похуй. Главное — она позволяет работать с асинхронными потоками данных, не блокируя твои драгоценные треды, как это делает обычное, старое, доброе синхронное говно.
Основные абстракции, которые тебе надо запомнить, чтобы не выглядеть идиотом:
Mono<T>— это как обещание, что тебе, может быть, прилетит один элемент. Или нихуя. Ноль или один. Как шанс, что твой заказ доставят, а может, и нет.Flux<T>— а вот это уже поток, последовательность. От нуля до овердохуища элементов. Как лента в соцсетях — может быть пусто, а может тебя заспамить так, что глаза на лоб вылезут.
Вот, смотри, как это выглядит в коде, простейший пример:
Flux.just("Apple", "Banana", "Cherry")
.filter(fruit -> fruit.length() > 5)
.map(String::toUpperCase)
.doOnNext(System.out::println)
.subscribe(); // А вот это, сука, волшебный пендель! Без подписки — нихуя не произойдёт.
А теперь ключевые фишки, без которых ты нихуя не поймёшь:
-
Ленивость (Lazy): Это, блядь, самое важное. Весь этот твой красивый пайплайн из
map,filter— это просто рецепт. Пока ты не вызвалsubscribe(), нихуя не вычисляется. Как будто ты составил список дел, но нихуя не делаешь. Классика. -
Операторов — дохуя:
map,filter,flatMap(этот, сука, коварный),zip,merge. Ими можно крутить-вертеть потоки, как хочешь. Главное — не запутаться и не сделатьflatMapтам, где хватило быmap, а то производительность накроется медным тазом. -
Ошибки — они везде: Поток может упасть. Для этого есть
onErrorResume,onErrorReturn. По сути, говоришь: «Э, братан, если тут пиздец случится, давай сделаем вот так...». -
Планировщики (Schedulers): Это чтобы контролировать, на каком потоке что выполняется.
Schedulers.parallel(),subscribeOn,publishOn. Если начнёшь в них копаться без понимания — гарантированно выстрелишь себе в ногу, причём из реактивного гранатомёта. -
Backpressure: А вот это, ёпта, крутая штука. Это когда подписчик (тот, кто данные потребляет) может сказать издателю (тому, кто их produces): «Охуел, что ли? Не гони так быстро, я не успеваю!». И издатель притормаживает. Без этого в реактивщине — пиздец и OutOfMemory.
Где это, блядь, применяется? Да везде, где хотят быть модными и высоконагруженными. В Spring WebFlux для реактивных апишек, с реактивными драйверами к базам (типа R2DBC), с WebClient для неблокирующих HTTP-вызовов. В общем, если видишь в описании вакансии «реактивное программирование» — готовься, щас будут задачки на Flux и Mono, где половину времени ты будешь гадать, почему у тебя ничего не выводится (потому что забыл subscribe(), мудак!).