Zip: попарная комбинация элементов
Zip — объединяет элементы из потоков попарно: берёт первый от первого, первый от второго и т.д., применяя функцию для слияния. Завершается, когда любой поток исчерпан. Идеален для синхронизации: например, zip координат X и Y в точки.
Пример:
Почему zip решает проблемы? Вместо ручных семафоров или ожиданий в циклах, декларативно комбинируете асинхронные источники. Backpressure: запрашивает у всех равномерно.
CombineLatest: комбинация последних элементов
CombineLatest — выдаёт комбинацию последних элементов от каждого потока, как только любой обновляется. Не ждёт пар — всегда использует свежие. Идеален для реального времени: например, комбинация курсов валют.
Пример:
В отличие от zip (строгие пары), здесь — динамика. Backpressure: как в merge.
Другие комбинации: withLatestFrom и concatMap
WithLatestFrom: похож на combineLatest, но "master"-поток (основной) триггерит выдачу, беря последние из второстепенных. Пример: flux.withLatestFrom(other, (main, other) -> main + other).
ConcatMap: как flatMap, но последовательный (как concat внутри). Для orderly асинхронных подпотоков.
Эти дополняют: выбирайте по сценарию — последовательность (concat/concatMap), параллелизм (merge/flatMap) или синхронизация (zip/combineLatest).
Практические советы и подводные камни
Ошибки: по умолчанию onError останавливает всё — используйте onErrorResume для продолжения.
Параллелизм: в merge/flatMap устанавливайте prefetch (буфер) или concurrency для тюнинга.
Камень: бесконечные потоки в merge — рискуете OOM; добавьте take() или limitRate().
Тестирование: StepVerifier.create(Flux.merge(f1, f2)).expectNextMatches(...).verify();
#Java #middle #Reactor #Concat #Merge #Zip #CombineLatest
Zip — объединяет элементы из потоков попарно: берёт первый от первого, первый от второго и т.д., применяя функцию для слияния. Завершается, когда любой поток исчерпан. Идеален для синхронизации: например, zip координат X и Y в точки.
Пример:
Flux<Integer> xCoords = Flux.just(1, 2, 3);
Flux<Integer> yCoords = Flux.just(10, 20, 30, 40); // Лишний элемент игнорируется
Flux<String> points = Flux.zip(xCoords, yCoords, (x, y) -> "(" + x + ", " + y + ")");
points.subscribe(System.out::println); // Вывод: "(1, 10)", "(2, 20)", "(3, 30)"
Здесь zip ждёт пару: если один медленный — задерживает. Для >2 потоков: zip(tuple -> ..., flux1, flux2, flux3).
Почему zip решает проблемы? Вместо ручных семафоров или ожиданий в циклах, декларативно комбинируете асинхронные источники. Backpressure: запрашивает у всех равномерно.
CombineLatest: комбинация последних элементов
CombineLatest — выдаёт комбинацию последних элементов от каждого потока, как только любой обновляется. Не ждёт пар — всегда использует свежие. Идеален для реального времени: например, комбинация курсов валют.
Пример:
Flux<String> stockA = Flux.just("A:100", "A:110").delayElements(Duration.ofSeconds(1));
Flux<String> stockB = Flux.just("B:200").delayElements(Duration.ofSeconds(2));
Flux<String> latest = Flux.combineLatest(stockA, stockB, (a, b) -> a + " + " + b);
latest.subscribe(System.out::println); // Вывод примерно: "A:100 + B:200" (после 2с), "A:110 + B:200" (ещё 1с после)
Здесь combineLatest реагирует на изменения: при обновлении A использует последний B. Для >2: combineLatest(tuple -> ..., fluxes).
В отличие от zip (строгие пары), здесь — динамика. Backpressure: как в merge.
Другие комбинации: withLatestFrom и concatMap
WithLatestFrom: похож на combineLatest, но "master"-поток (основной) триггерит выдачу, беря последние из второстепенных. Пример: flux.withLatestFrom(other, (main, other) -> main + other).
ConcatMap: как flatMap, но последовательный (как concat внутри). Для orderly асинхронных подпотоков.
Эти дополняют: выбирайте по сценарию — последовательность (concat/concatMap), параллелизм (merge/flatMap) или синхронизация (zip/combineLatest).
Практические советы и подводные камни
Ошибки: по умолчанию onError останавливает всё — используйте onErrorResume для продолжения.
Параллелизм: в merge/flatMap устанавливайте prefetch (буфер) или concurrency для тюнинга.
Камень: бесконечные потоки в merge — рискуете OOM; добавьте take() или limitRate().
Тестирование: StepVerifier.create(Flux.merge(f1, f2)).expectNextMatches(...).verify();
#Java #middle #Reactor #Concat #Merge #Zip #CombineLatest
👍3
Что выведет код?
#Tasks
public class Task081025 {
public static void main(String[] args) {
try {
System.out.print("A");
throw new RuntimeException();
} catch (RuntimeException e) {
System.out.print("B");
throw new NullPointerException();
} finally {
System.out.print("C");
throw new IllegalArgumentException();
}
}
}
#Tasks
👍2
Вопрос с собеседований
Что лучше: throw или return кода ошибки?🤓
Ответ:
В Java принято использовать исключения (throw), а не коды ошибок.
Исключения позволяют разделить бизнес-логику и обработку ошибок, делать код чище и поддерживаемее.
Коды ошибок уместны в низкоуровневых системах, но не в Java-приложениях.
#собеседование
Что лучше: throw или return кода ошибки?
Ответ:
Исключения позволяют разделить бизнес-логику и обработку ошибок, делать код чище и поддерживаемее.
Коды ошибок уместны в низкоуровневых системах, но не в Java-приложениях.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3