Конечно, Роман прав, что Java Future
не позволяет вам предоставить обратный вызов, когда работа завершена.
Тем не менее, это дает вам возможность проверить, выполнена ли работа,и если это так, то вызов .get()
не будет блокировать.
К счастью для нас, у нас также есть дешевый способ перенаправить поток, чтобы быстро выполнить проверку опроса через сопрограммы.
Давайте напишем эту логику опроса, а также продадим ее как метод расширения:
suspend fun <T> Future<T>.wait(): T {
while(!isDone)
delay(1) // or whatever you want your polling frequency to be
return get()
}
Затем используем:
fun someBlockingWork(): Future<String> { ... }
suspend fun useWork() {
val result = someBlockingWork().wait()
println("Result: $result")
}
Таким образом, у нас есть время отклика в миллисекундах на завершение нашего будущего без использования каких-либодополнительные потоки.
И, конечно, вы захотите добавить верхнюю границу для использования в качестве тайм-аута, чтобы не ждать вечно.В этом случае мы можем немного обновить код:
suspend fun <T> Future<T>.wait(timeoutMs: Int = 60000): T? {
val start = System.currentTimeMillis()
while (!isDone) {
if (System.currentTimeMillis() - start > timeoutMs)
return null
delay(1)
}
return get()
}