Введение в Kotlin Flow

kotlin

Into the Flow: Kotlin cold streams primer — одна из лучших статей о новой возможности Kotlin под названием Flow.

Введение в Kotlin Flow

В Kotlin уже есть мощный механизм асинхронного программирования под названием короутины (coroutines). Они позволяют писать чистый асинхронный неблокируемый код, построенный на последовательном вызове функций. Например, мы можем объявить такую функцию:

Допустим, она будет выполнять сложные расчеты в фоне, а затем вернет результат в виде списка. Это отлично работает, за исключением того, что функция должна заранее выполнить расчет всех элементов списка. Если элементов слишком много или мы имеем дело с неопределенным количеством элементов, начинаются проблемы.

РЕКОМЕНДУЕМ:
Полезные советы разработчику на Kotlin

Для их решения в Kotlin есть другой инструмент под названием Flow (поток):

Обрати внимание, что при объявлении функции мы не использовали ключевое слово suspend. Это потому, что на самом деле, какой бы сложной ни была функция, при запуске она ничего не делает и сразу возвращает управление. Функция начинает работать только после того, как мы вызовем метод collect() полученного от функции объекта. Например:

Именно поэтому разработчики Kotlin называют потоки холодными, в противовес горячим каналам (Channel), которые также присутствуют в языке.

Для создания самого потока можно использовать функцию flow:

В данном случае функция «выпускает» в поток три объекта типа Int с перерывом в 100 миллисекунд. Обрати внимание, что flow — это suspend-функция, которая может запускать другие suspend-функции (в данном случае delay()).

Как уже было сказано выше, функция, возвращающая поток, не должна быть suspend-функцией. Но метод collect() объекта типа Flow — suspend-функция, которая должна работать внутри CoroutineScope:

Создать поток можно и другими способами, например с помощью метода asFlow():

Завершить поток возможно несколькими способами — от вызова collect() до методов типа first(), fold(), toList(), знакомых тебе по работе с коллекциями.

Сам поток можно трансформировать, чтобы получить новый поток с помощью методов map(), filter(), take():

По умолчанию функции flow и collect запускаются внутри текущего CoroutineScope, но его можно изменить, используя метод flowOn():

Несколько потоков можно объединить в один с помощью метода zip():

Этот код объединит каждый элемент первого потока с соответствующим элементом второго потока:

Другой вариант объединения — функция combine():

В данном случае каждый элемент первого потока будет объединен с последним элементом второго потока:

После трансформации потоков мы можем получить структуры данных, включающие в себя потоки потоков ( Flow<Flow<X>>). Чтобы «выровнять» такие данные, можно использовать один из следующих методов:

  • flatMapConcat() — возвращает поток, который возвращает все элементы первого вложенного потока, затем все элементы второго потока и так далее;
  • flatMapMerge() — возвращает поток, в который попадают элементы из всех вложенных потоков в порядке очередности;
  • flatMapLatest() — возвращает последний вложенный поток.

РЕКОМЕНДУЕМ:
Хорошие и плохие приемы программирования на Kotlin

На этом все. Теперь вы знаете, что представляет Kotlin Flow.

Понравилась статья? Поделиться с друзьями:
Комментарии: 2
  1. Den

    Нихрена не понятно, но очень интересно!

    1. zalupka

      Согласен, ничего не понятно

Добавить комментарий