Разница Await.ready и Await.result

Я знаю, что это довольно открытый вопрос, и я извиняюсь.

Я вижу, что Await.ready возвращает Awaitable.type а Await.result возвращает T но я все еще путаю их.

В чем разница между ними?

Является ли одна блокировка, а другая - неблокирующей?

Ответы

Ответ 1

Они оба блокируются до тех пор, пока будущее не завершится, разница - это только их тип возврата.

Разница полезна, когда ваше Future выдает исключения:

def a = Future { Thread.sleep(2000); 100 }
def b = Future { Thread.sleep(2000); throw new NullPointerException }

Await.ready(a, Duration.Inf) // Success(100)
Await.ready(b, Duration.Inf) // Failure(java.lang.NullPointerException)

Await.result(a, Duration.Inf) // 100
Await.result(b, Duration.Inf) // crash with java.lang.NullPointerException

Ответ 2

В общем, обе блокируют.

Разница в том, что Await.ready блокируется до тех пор, пока будущее не закончится (успешно или неудачно) в заданное время.

Единственное различие заключается в том, что ready блоки до тех пор, пока Awaitable будет готов, и result приведет к типу результата T

Postscriptum: На практике, если вы хотите выполнить некоторые действия, такие как проверка ошибок или ведение журнала, вы должны взять Await.ready(...) если хотите составить результат и выбросить ошибку, если что-то пойдет не так, возьмите Await.result(...).

Как правило - старайтесь избегать Await.

Ответ 3

Оба блокируют не более заданной Duration. Тем не менее, result пытается вернуть результат в будущем сразу же и выдает исключение, если будущее не удалось, в то время как ready возвращает законченное будущее, из которого можно безопасно извлечь результат (Success или Failure) через свойство value.

Последнее очень удобно, когда вам приходится иметь дело и с таймаутом:

val future = Future { Thread.sleep(Random.nextInt(2000)); 123 }

Try(Await.ready(future, 1.second)) match {
    case Success(f) => f.value.get match {
      case Success(res) => // handle future success 
      case Failure(e) => // handle future failure
    }
    case Failure(_) => // handle timeout
}

При использовании result "тайм-аут" и исключения из неудачных фьючерсов "перепутаны".