Есть ли у Kotlin coroutines асинхронный вызов с таймером?
делает Котлин имеет возможность вызвать функцию async() в с сопрограмм некоторое время, ведьма вернет результат по умолчанию после завершения времени?
я обнаружил, что можно только вызвать await, и чем бесконечность ждать результата.
async {
...
val result = computation.await()
...
}
но реальный производственный случай, чем вам нужно, чтобы вернуть результат по умолчанию или исключение. Что такое правильный способ сделать что-то в Kotlin coroutines? Вроде что-то похожее на это:
async {
...
val timeout = 100500
val result: SomeDeferredClass = computation.await(timeout)
if (result.isTimeout()) {
// get default value
} else {
// process result
}
...
}
2 ответов
можно использовать withTimeout
-функция. Он бросит CancellationException
когда он истекает. Вы можете поймать это исключение и вернуть значение по умолчанию.
что-то вроде этого:
async {
...
val timeout = 100500L
try {
withTimeout(timeout) {
computation.await()
}
...
} catch (ex: CancellationException) {
defaultValue
}
}
вы также можете использовать withTimeoutOrNull
-функция, которая возвращает null
по таймауту. Вот так:
async {
...
val timeout = 100500L
withTimeoutOrNull(timeout) { computation.await() } ?: defaultValue
}
этот подход не позволит вам различать тайм-аут и вычисление, которое возвращает null, хотя. Значение по умолчанию будут возвращены в случаи.
для получения дополнительной информации см. здесь: https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#timeout
сочетания обоих расширения и решение @marstran я пришел к решению, которое может лучше соответствовать вашим требованиям наличия await
функция с таймаутом и значением по умолчанию. Также я думаю, что это более чистое решение
просто определите функцию расширения:
suspend fun <T> Deferred<T>.await(timeout : Long, defaultValue : T) =
withTimeoutOrNull(timeout) { await() } ?: defaultValue
и вы можете использовать его в любом месте. Вместо
async {
...
val timeout = 100500L
withTimeoutOrNull(timeout) { computation.await() } ?: defaultValue
}
вы можете сделать просто
async {
val timeout = 100500L
computation.await(timeout, defaultValue)
}