Есть ли у 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)
}