Сбор потока в области в Kotlin
Функция collect внутри runBlocking
удобен для примеров, но в приложении сбор часто
живет рядом с другими корутинами. Функция launchIn
стартует прием потока в переданной
CoroutineScope и возвращает Job,
не блокируя вызывающий код.
В coroutineScope можно запустить сбор
фоном и продолжить основную линию:
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
suspend fun watch() = coroutineScope {
val ticks = flow {
emit("a")
delay(30)
emit("b")
}.onEach { ch -> println(ch) }
ticks.launchIn(this)
println("setup")
}
fun main() {
runBlocking {
watch()
println("done")
}
}
"setup" может появиться до букв из
потока, а "done" - после завершения
coroutineScope, когда сбор через
launchIn тоже закончился.
Отмена области останавливает и связанный
Job сбора:
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
suspend fun shortWatch() = coroutineScope {
flow {
repeat(5) { i ->
delay(20)
emit(i)
}
}.onEach { n -> println(n) }
.launchIn(this)
}
fun main() {
runBlocking {
shortWatch()
}
}
Пока coroutineScope активна, launchIn
держит прием открытым. Выход из области
дожидается завершения или отмены дочернего
Job так же, как у обычного launch.
В coroutineScope опишите поток из
двух строк "L" и "R" и
запустите его сбор через launchIn с
печатью каждой строки. После области выведите
"tail" из runBlocking.
Поток отдает числа 0 и 1 с
короткой delay между ними. Подключите
onEach для вывода и повесьте сбор на
launchIn текущей области.