Ответ
concatMap — оператор преобразования в RxJava, который применяет функцию к каждому элементу потока и объединяет результаты в один последовательный поток. В отличие от flatMap, он сохраняет порядок элементов.
Observable.just(1, 2, 3)
.concatMap { number ->
Observable.just("A$number", "B$number").delay(100, TimeUnit.MILLISECONDS)
}
.subscribe { println(it) }
Вывод будет строго по порядку: A1, B1, A2, B2, A3, B3. Если задержки разные, concatMap дождётся завершения предыдущего Observable перед обработкой следующего. Полезен, когда важен порядок или нужно избежать перегрузки (например, для последовательных сетевых запросов).
Ответ 18+ 🔞
Ну слушай, вот есть такая штука в RxJava — concatMap. Представь себе, что ты стоишь в очереди в столовую, и каждый, кто заходит, должен сначала полностью получить свой обед, и только потом следующий начинает заказывать. Вот concatMap работает примерно так же, только с потоками данных.
Если взять flatMap — это как если бы все в очереди одновременно начали орать свои заказы, и повара бы мешали всё в кучу. А concatMap — это культурный, последовательный мужик, который ждёт, пока предыдущий поток полностью выдохнется, и только потом запускает следующий. Порядок — его всё.
Вот смотри на код, тут всё понятно:
Observable.just(1, 2, 3)
.concatMap { number ->
Observable.just("A$number", "B$number").delay(100, TimeUnit.MILLISECONDS)
}
.subscribe { println(it) }
Что тут происходит? Берём числа 1, 2, 3. Для каждой цифры мы создаём новый маленький поток, который выдаёт две буквы с этим числом — A1, B1, и так далее. Искусственно добавляем задержку, чтобы было похоже на сетевой запрос, например.
И что на выходе? А на выходе будет строгая последовательность, ёпта: A1, B1, A2, B2, A3, B3. Никаких тебе скачков. Даже если бы задержки у каждого внутреннего потока были разными — concatMap бы терпеливо ждал, как святой, пока первый не закончится, потом запускал второй. Никакой спешки.
А где это полезно? Да везде, где порядок — святое. Например, ты шлёшь на сервер запросы на обновление профиля: сначала имя, потом аватарку, потом статус. Если их запулить параллельно через flatMap — сервер может охуеть и всё перепутать, получится пиздец. А через concatMap — всё чинно, благородно, по очереди. Или когда у тебя лимит на запросы, и ты не хочешь перегрузить бедный бэкенд — concatMap не даст создать овердохуища одновременных вызовов.
Короче, если нужен порядок и контроль — твой выбор concatMap. Если можно всё в одну кучу и похуй на последовательность — тогда flatMap. Всё просто, как три копейки.