В первом варианте вы получаете Deferred<Int>
для обоих асинхронных вызовов.Как документация Deferred
показывает, что есть несколько состояний, в которых может находиться отложенный объект. Снаружи это состояние теперь либо new
, либо active
, но, конечно, еще не завершено.Однако в вашем втором варианте для первого async-await уже требуется состояние completed
, иначе вы не могли бы иметь никакого значения.Однако о вашем async{one()}.await()
втором async
пока ничего не известно.Также обратите внимание, что возвращаемое значение await()
теперь равно Int
, а не Deferred
, поэтому сопрограмма должна была быть выполнена к тому времени.Проверьте также документацию await()
.
Другими словами:
val one = async { one() }
val two = async { two() }
И one
, и two
теперь Deferred<Int>
.Ни один еще не был вызван (или, возможно, еще не был вызван).Как только вы позвоните one.await()
, он может начать уже и one
, и two
, просто потому, что у него есть ресурсы для этого (даже если вы нигде не использовали two.await()
в своем коде).
Во втором варианте, однако:
val one = async { one() }.await()
val two = async { two() }.await()
Даже если он создает сопрограмму для async {one()}
, он должен немедленно установить значение one
, потому что вы вызываете await()
для него.Типы one
и two
оба Int
.Поэтому, как только будет нажата первая из этих строк, асинхронный код должен быть выполнен немедленно.К тому времени никто не знает, что еще один асинхронный вызов должен быть выполнен, пока мы ожидаем значения первого.Если у первого не будет await
, сопрограмма будет снова выполняться параллельно, например:
val one = async { one() }
val two = async { two() }.await()
выполнит one()
и two()
параллельно.
Так что, возможно, это можно обобщить так: только те сопрограммы могут выполняться параллельно в ожидании, которые к тому времени известны / порождаются.