flatMapConcat vs Merge vs LatestВам нужно взять поток ID-шников и для каждого скачать детали из сети. Задача банальная:
val detailsFlow = idsFlow.flatMap??? { id ->
repository.fetchDetailsAsFlow(id)
}
IDE услужливо подсказывает три варианта:
Concat, Merge, Latest. И вот тут кроется разница между "работает как часы", "тормозит" и "тихо теряет данные".Давайте разберем на пальцах.
1.
flatMapConcat (Очередь в поликлинику)• Как работает: Строго последовательно. Ждет, пока полностью завершится внутренний Flow для первого ID, и только потом переходит ко второму.
• Плюс: Сохраняет идеальный порядок элементов. Безопасно для транзакций/БД.
• Минус (Bottleneck): Это ОЧЕНЬ медленно. Если у вас 10 картинок, и каждая качается по секунде - весь процесс займет 10 секунд. Никакой параллельности.
2.
flatMapMerge (Броуновское движение)• Как работает: Запускает сбор внутренних Flow параллельно. Не ждет окончания предыдущего.
• Плюс: Максимальная скорость. 10 картинок скачаются (почти) за 1 секунду.
• Минус: Порядок ответов непредсказуем. Если вам важно, чтобы элементы пришли в том же порядке, что и ушли — вы получите race condition.
• 🧠 Секрет Сеньора: У него есть параметр
concurrency (по дефолту 16). Если поставить flatMapMerge(concurrency = 1), он превратится в flatMapConcat.3.
flatMapLatest (Амнезия)• Как работает: Как только в верхний (внешний) поток прилетает новый элемент, он отменяет выполнение предыдущего внутреннего потока.
• Плюс: Идеально для UI (например, строка поиска). Юзер ввел "A" -> пошел запрос. Ввел "AB" -> запрос для "A" отменился (вылетел
CancellationException), пошел запрос для "AB". Экономит трафик и ресурсы.• Фатальный Минус: НИКОГДА не используйте это для сохранения данных или платежей. Если вы отправите два события на сохранение подряд, первое будет убито на полпути.
📝 Чек-лист для код-ревью:
✅ Поиск с автокомплитом? ->
flatMapLatest✅ Скачивание списка файлов, порядок не важен? ->
flatMapMerge✅ Строгая последовательная обработка платежей или логов? ->
flatMapConcatА какой из них вы чаще всего ставите по привычке, пока профайлер не заставит задуматься? 👇
✍️ @kotlin_lib