#kotlin #kotlin-coroutines
Вопрос:
Я хочу создать сопрограммы Kotlin Flow
, которые будут выдавать значения, когда
- они меняются, и
- периодически выдает последнее доступное значение, каждые x секунд с момента последнего изменения или последнего выброса.
Ответ №1:
Похоже, это работает-каждый раз, когда приходит новое значение, transformLatest
отменяет все предыдущие лямбды и запускает новую. Таким образом, этот подход излучает, а затем продолжает периодически излучать, пока не появится новое значение.
flow.transformLatest { value ->
while(currentCoroutineContext().isActive) {
emit(value)
delay(x)
}
}
Комментарии:
1. Вы можете отказаться от
isActive
чека. Отмена будет работать так же.2. Верно, но
while
петли без условий меня раздражают. Мне нравится дополнительная часть ума, которую обеспечивает явная проверка.
Ответ №2:
Вы можете создать Flow
устройство, которое излучает через регулярные промежутки времени, а затем просто использовать combine
. Каждый раз, когда вы объединяете значения, вы на самом деле просто передаете текущее значение Flow
интересующего вас оригинала.
// This is the main flow you are interested in. This uses
// a Flow builder just as a simple example but this could
// be any kind of Flow, like a (Mutable)StateFlow.
val emitter = flow {
emit("Your data")
// ...
}
// This just serves as a timer.
val timer = flow {
while (currentCoroutineContext().isActive) {
emit(Unit)
delay(500)
}
}
// This will emit whenever either of the Flows emits and
// continues to do so until "emitter" stops emitting.
combine(
emitter,
timer
) { value, ticker ->
// Always just return the value of your
// main Flow.
value
}
Комментарии:
1. Это прекратится, когда закончится последний выброс
2. @ShawnThye уверен, но это предполагает, что есть последний «выброс». Я использовал здесь построитель потоков только для того, чтобы иметь самодостаточный пример, но, по-видимому, мы говорим о том, чтобы начать с другого потока, который никогда не «заканчивается». И если они начинают с потока, который действительно заканчивается, возможно, они хотели бы, чтобы общий поток тоже закончился. Но все сводится к тому, что они ищут. Я лично уже в настоящее время использую это решение при объединении потока «тикера», как я предложил, с потоком MutableStateFlow.
3. Да, я думаю, что в его случае ему нужно использовать MutableShareFlow или MutableStateFlow в зависимости от его области применения 🙂