Dans la première variante, vous obtenez un Deferred<Int>
pour les deux appels asynchrones. En tant que la documentation de Deferred
montre bien qu'il existe plusieurs états dans lesquels l'objet différé peut se trouver. Vu de l'extérieur, cet état est soit new
o active
mais sûrement pas encore achevée. Dans votre deuxième variante, cependant, le premier async-await a besoin d'un completed
Sinon, vous n'auriez aucune valeur dans ce domaine. Cependant, sur votre async{one()}.await()
le deuxième async
n'est pas encore connue. Notez également que la valeur de retour de await()
est maintenant Int
et non Deferred
la coroutine doit donc avoir été exécutée à ce moment-là. Vérifier également la documentation de await()
.
En d'autres termes :
val one = async { one() }
val two = async { two() }
Les deux one
y two
sont maintenant Deferred<Int>
. Aucun n'a encore été appelé (ou pourrait l'avoir été). Dès que vous appelez one.await()
Il se peut qu'il ait déjà commencé les deux one
y two
simplement parce qu'il dispose des ressources nécessaires (même si vous n'avez pas utilisé la fonction two.await()
n'importe où dans votre code).
En revanche, pour la deuxième variante :
val one = async { one() }.await()
val two = async { two() }.await()
Même s'il crée une coroutine pour async {one()}
il doit attribuer une valeur à one
immédiatement, car vous appelez await()
sur celui-ci. Les types de one
y two
sont tous deux Int
. Ainsi, dès que la première de ces lignes est atteinte, le code asynchrone doit être exécuté immédiatement. Personne ne sait alors qu'un autre appel asynchrone doit être exécuté pendant que nous attendons la valeur de la première ligne. Si la première n'avait pas de await
la coroutine sera à nouveau exécutée en parallèle, par exemple :
val one = async { one() }
val two = async { two() }.await()
exécutera one()
y two()
en parallèle.
On peut donc peut-être résumer cela en disant que seules les coroutines qui sont connues/spawnées à ce moment-là peuvent être exécutées en parallèle lors d'un await.