Как запустить Kotlin Flow, но задержать результат, который он возвращает, на определенное время, если он завершится раньAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как запустить Kotlin Flow, но задержать результат, который он возвращает, на определенное время, если он завершится рань

Сообщение Anonymous »

Я пытаюсь создать поток, который «модифицирует» текущий поток, ожидая по крайней мере определенное время, прежде чем вернуть первый результат.
Я бы хотел, конечно, чтобы сразу начать обработку текущего потока, но «придерживать» результат до тех пор, пока не пройдет это время.
Мне это нужно в приложении для Android, которое я сейчас пишу, потому что, если что-то будет загружается достаточно быстро, поток завершится во время перехода входа NavHost, что приведет к зависанию.
Конечно, альтернативой было бы немедленно запустить запрос (не HTTP, извините) и ожидаю завершения перехода, но боюсь, что решение будет похоже на это (за исключением того, что поток «ожидания» будет отличаться от задержки).
Я узнал о потоке zip, потому что там написано:

Значения из текущего потока (this) сжимаются с другим потоком, используя предоставленную функцию преобразования. применяется к каждой паре значений. Результирующий поток завершается, как только завершается один из потоков, и в оставшемся потоке вызывается метод отмены.

И вот пример:

Код: Выделить всё

val flow = flowOf(1, 2, 3).onEach { delay(10) }
val flow2 = flowOf("a", "b", "c", "d").onEach { delay(15) }
flow.zip(flow2) { i, s -> i.toString() + s }.collect {
println(it) // Will print "1a 2b 3c"
}
В этом примере оставшийся элемент «d» отбрасывается.
Последняя фраза — это то, что я вижу в мой код.
Поток «ожидания» не отменяется автоматически после завершения zip.
Поскольку я также перезапускаю этот поток при обновлении по запросу, в следующий раз, когда он зависнет (не произойти без этой задержкиResultByAtLeast).
Это мой код, и из LogCat я могу видеть только:

СТАРТ

ЗАДЕРЖКА: L: 252

но я не вижу «КОНЕЦ»...

Код: Выделить всё

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.zip
import kotlin.time.Duration

/**
* Waits [d] to produce a result if the result of the current flow is ready before [d].
* For example, if [d] is 5 seconds and the result of the current flow is ready at `t = 2 seconds`,
* this "modifier" will wait another 3 seconds before returning the result.
*
* If, instead, the result is ready at `t = 7 seconds`, return it when it's ready.
*
* @param d the minimum time to wait for the result.
*/
fun  Flow.delayResultByAtLeast(d: Duration): Flow {
val waitFlows = flow {
val ctx = currentCoroutineContext()

Log.d("FLOW", "START")
val start = System.currentTimeMillis()

delay(d)

val end = System.currentTimeMillis()
val delta = end - start
Log.d("FLOW", "DELAY: L: $delta")

while(ctx.isActive) {
emit(Unit)
}

Log.d("FLOW", "END")
}

return this.zip(waitFlows) { a, _ -> a }
}
Есть ли способ автоматически отменить другой поток после завершения первого?
Или этот подход совершенно неправильный? (Кстати, возможно, это потому, что я впервые использую Kotlin Flow и Jetpack Compose).


Подробнее здесь: https://stackoverflow.com/questions/790 ... n-amount-o
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»