Действие на каждом значении в Kotlin
Иногда нужно залогировать или обновить счетчик
на пути к collect, не меняя сами
данные. Функция onEach принимает действие и
возвращает тот же Flow: элемент
проходит дальше после выполнения лямбды.
Метку можно печатать перед финальным приемом, сохраняя исходные строки:
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
flowOf("alpha", "beta")
.onEach { token -> println("seen $token") }
.collect { token ->
println("got $token")
}
}
}
Для каждого токена сначала строка "seen ...",
затем "got ...". Функция onEach не
заменяет и не фильтрует значения.
Несколько onEach подряд образуют
цепочку наблюдений перед другими операторами:
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
flowOf(2, 3)
.onEach { n -> println("raw $n") }
.map { n -> n + 1 }
.onEach { n -> println("plus $n") }
.collect { n ->
println("end $n")
}
}
}
Видны этапы "raw", "plus" и
"end" для каждого числа. Порядок
операторов задает, на какой стадии срабатывает
наблюдение.
Поток из 1 и 2 перед сбором
должен печатать слово "tick" на
каждом элементе через onEach, затем
выводить само число в collect.
Три буквы "p", "q", "r"
пройдите через onEach с выводом
длины строки, после чего соберите исходные
буквы без изменений.