Flow — это асинхронный стрим данных в Kotlin Coroutines, аналог Rx, но в корутинном стиле. Его важно понимать и уметь отличать от Sequence и suspend-функций.
Flow<T> — это тип, представляющий ленивый асинхронный поток значений, который эмитит (emit) несколько значений во времени, при этом не блокируя поток.
fun numbers(): Flow<Int> = flow {
for (i in 1..3) {
emit(i)
delay(100) // не блокирует поток!
}
}
Ключевые свойства Flow
- Cold (холодный) — не начнёт работу, пока не начнёшь
collect - Асинхронный:
delay,network,dbвнутриflow {}не блокируют - Structured concurrency:
flowживёт вCoroutineScope
Чем отличается от других?
| Сравнение | suspend fun | Sequence | Flow |
|---|---|---|---|
| Кол-во значений | Одно (T) | Много (T) | Много (T) |
| Асинхронность | да (не блокирует) | нет (блокирует) | да (не блокирует) |
| Отложенность (lazy) | нет | да | да |
| Прерывание | Через cancel() scope | нельзя | через collect или scope |
| Backpressure | нет | нет | поддерживает |
Частые ошибки в применении Flow
| Ошибка | Почему проблема |
|---|---|
flow.collect {} в UI без диспетчера | Может заблокировать UI |
collect() без launch в ViewModel | Блокирует suspend-функцию |
collect() вне скоупа | Приведёт к утечке или падению |