Какие операторы 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 — для сценариев с обновлением состояния, где актуален только последний ввод (поиск, автокомплит).
Эти операторы — ключевые инструменты реактивной архитектуры и позволяют гибко управлять потоками, не перегружая логику ручными отменами и переключениями.