Какие операторы Flow (например, flatMapConcat, flatMapMerge, flatMapLatest) используются и для чего?

В Kotlin Flow из библиотеки kotlinx.coroutines.flow есть мощные операторы преобразования потоков данных, такие как:

  • flatMapConcat

  • flatMapMerge

  • flatMapLatest

Все они принимают входной Flow, применяют к каждому элементу новый вложенный Flow, и затем объединяют результаты. Разница между ними — в стратегии объединения.

🔷 flatMapConcat

📌 Поведение:

  • Обрабатывает элементы последовательно, один за другим.

  • Ждёт, пока вложенный Flow завершится, прежде чем перейти к следующему.

✅ Используйте, когда:

  • Порядок важен.

  • Каждому элементу нужно уделить «время».

  • Необходимо избежать параллелизма.

Пример:

flowOf(1, 2, 3)
.flatMapConcat { value ->
flow {
emit("Start $value")
delay(100)
emit("End $value")
}
}
.collect { println(it) }

📤 Вывод:

Start 1
End 1
Start 2
End 2
Start 3
End 3

🔶 flatMapMerge

📌 Поведение:

  • Запускает все вложенные Flow параллельно.

  • Не ждёт, пока предыдущий закончится.

  • Результаты приходят по мере готовности, без гарантии порядка.

✅ Используйте, когда:

  • Параллелизм важен (например, сетевые запросы).

  • Порядок не критичен.

  • Хотите максимальную скорость.

Пример:

flowOf(1, 2, 3)
.flatMapMerge { value ->
flow {
delay((4 - value) \* 100L) // чтобы позже начавшие пришли раньше
emit("Done $value")
}
}
.collect { println(it) }

📤 Возможный вывод:

Done 3
Done 2
Done 1

🔴 flatMapLatest

📌 Поведение:

  • При появлении нового элемента отменяет текущий вложенный Flow и запускает новый.

  • Гарантирует, что в каждый момент работает только один вложенный Flowпоследний.

✅ Используйте, когда:

  • Нужно реагировать только на последний запрос (поиск, ввод пользователя).

  • Старые данные неактуальны и могут быть отменены.

Пример:

flowOf(1, 2, 3)
.onEach { delay(100) }
.flatMapLatest { value ->
flow {
emit("Start $value")
delay(200)
emit("End $value")
}
}
.collect { println(it) }

📤 Вывод:

Start 3
End 3

(вложенные Flows для 1 и 2 были отменены до завершения)

Сравнение

Оператор Порядок Параллелизм Отмена предыдущего
flatMapConcat ✅ Да ❌ Нет ❌ Нет
--- --- --- ---
flatMapMerge ❌ Нет ✅ Да ❌ Нет
--- --- --- ---
flatMapLatest ❌ Нет ❌ Нет ✅ Да
--- --- --- ---

Когда использовать

  • flatMapConcat — когда важен порядок (например, поэтапная обработка).

  • flatMapMerge — когда важна скорость, можно обрабатывать параллельно, и порядок не имеет значения.

  • flatMapLatest — для сценариев с обновлением состояния, где актуален только последний ввод (поиск, автокомплит).

Эти операторы — ключевые инструменты реактивной архитектуры и позволяют гибко управлять потоками, не перегружая логику ручными отменами и переключениями.