Это небольшая заметка о неочевидных моментах Kotlin Flow API и функции launchIn.
РЕКОМЕНДУЕМ:
- Как сделать код на Kotlin более понятным
- Хорошие и плохие приемы программирования на Kotlin
- Полезные советы разработчику на языке Kotlin
Представим, что нам необходимо собрать данные из Flow. Способ сделать это «в лоб» выглядел бы так:
1 2 3 4 5 |
scope.launch { flow .onEach { println(it) } .collect() } |
Однако «каноничный» способ будет другим:
1 2 3 |
flow .onEach { println(it) } .launchIn(scope) |
И это не просто синтаксический сахар. LaunchIn позволяет избежать весьма неочевидных проблем с приложением.
К примеру, когда нужно собрать данные из двух Flow, легко ошибиться и сделать это так:
1 2 3 4 5 6 7 8 |
scope.launch { flow1 .onEach { println(it) } .collect() flow2 .onEach { println(it) } .collect() } |
Ошибка здесь в том, что данные из двух Flow не будут собираться одновременно. Сначала будут получены все данные из flow1, и только затем начнется сбор flow2.
Исправить это неканоничным путем можно так:
1 2 3 4 5 6 7 8 |
scope.launch { flow1 .collect { println(it) } } scope.launch { flow2 .collect { println(it) } } |
Однако при использовании launchIn такого не возникнет в принципе:
1 2 3 4 5 6 |
flow1 .onEach { println(it) } .launchIn(coroutineScope) flow2 .onEach { println(it) } .launchIn(coroutineScope) |