Запас значений в Kotlin
По умолчанию emit приостанавливает
строитель, пока сборщик не обработает элемент.
Если обработка долгая, отправитель простаивает
на каждом шаге.
Оператор buffer вставляет между
строителем и сборщиком небольшой запас: пока
емкость не исчерпана, emit может
продолжаться, не дожидаясь конца лямбды
collect:
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val paced = flow {
repeat(3) { i ->
emit(i)
delay(20)
}
}.buffer()
paced.collect { value ->
delay(80)
println(value)
}
}
}
Строитель успевает подготовить несколько чисел,
пока сборщик занят паузой на приеме. Без
buffer каждая отправка ждала бы конца
медленного collect.
Размер запаса задают аргументом. Явная вместимость полезна, когда известно, сколько элементов может накопиться между шагами:
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val batch = flow {
emit("x")
emit("y")
}.buffer(capacity = 2)
batch.collect { token ->
println(token)
}
}
}
Оба токена доходят до сборщика в исходном
порядке. Функция buffer не меняет значения,
а лишь разносит скорость отправки и приема.
Поток отдает числа 1 и 2 с
короткой delay после каждого
emit. Подключите buffer и
при сборе делайте паузу 100
миллисекунд перед печатью.
Три строки "p", "q", "r"
отправьте из цикла, затем соберите поток с
buffer вместимостью 2 и
выведите их по порядку.