Kotlin是否有可能在一段时间内在协同程序中调用函数async(),在时间完成后会返回默认结果吗?
我发现只能调用await,而无限等待结果。
async {
...
val result = computation.await()
...
}
但是真实的生产案例比你需要返回默认结果或异常。什么是在Kotlin协同程序中做某事的正确方法?像这样的东西:
async {
...
val timeout = 100500
val result: SomeDeferredClass = computation.await(timeout)
if (result.isTimeout()) {
// get default value
} else {
// process result
}
...
}
答案 0 :(得分:11)
您可以使用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
答案 1 :(得分:1)
结合Extensions和@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)
}