Dans la kotlinx.coroutines
bibliothèque, vous pouvez démarrer une nouvelle coroutine en utilisant soit launch
(avec join
) ou async
(avec await
). Quelle est la différence entre eux?
la source
Dans la kotlinx.coroutines
bibliothèque, vous pouvez démarrer une nouvelle coroutine en utilisant soit launch
(avec join
) ou async
(avec await
). Quelle est la différence entre eux?
launch
est utilisé pour tirer et oublier la coroutine . C'est comme démarrer un nouveau fil. Si le code à l'intérieur de se launch
termine avec une exception, il est traité comme une exception non interceptée dans un thread - généralement imprimé sur stderr dans les applications JVM principales et plante les applications Android. join
est utilisé pour attendre la fin de la coroutine lancée et il ne propage pas son exception. Cependant, une coroutine enfant en panne annule également son parent avec l'exception correspondante.
async
est utilisé pour démarrer une coroutine qui calcule un résultat . Le résultat est représenté par une instance de Deferred
et vous devez l' utiliser await
. Une exception non interceptée à l'intérieur du async
code est stockée dans le résultat Deferred
et n'est livrée nulle part ailleurs, elle sera supprimée silencieusement à moins qu'elle ne soit traitée. Vous NE DEVEZ PAS oublier la coroutine que vous avez commencée avec async .
Je trouve ce guide https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md utile. Je citerai les parties essentielles
🦄 coroutine
Vous pouvez donc considérer la coroutine comme quelque chose qui gère les threads de manière très efficace.
🐤 lancement
Alors
launch
démarre un thread d'arrière-plan, fait quelque chose et renvoie un jeton immédiatement commeJob
. Vous pouvez appelerjoin
celaJob
pour bloquer jusqu'à ce que celaunch
fil soit terminé🦆 asynchrone
Alors
async
démarre un thread d'arrière-plan, fait quelque chose et renvoie un jeton immédiatement commeDeferred
.Alors
Deferred
est en fait unJob
. Voir https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html🦋 async est impatient par défaut
la source
launch
etasync
sont utilisés pour démarrer de nouvelles coroutines. Mais, ils les exécutent de manière différente.Je voudrais montrer un exemple très basique qui vous aidera à comprendre la différence très facilement
Dans cet exemple, mon code télécharge 3 données en cliquant sur le
btnCount
bouton et affichepgBar
la barre de progression jusqu'à ce que tout le téléchargement soit terminé. Il y a 3suspend
fonctionsdownloadTask1()
,downloadTask2()
etdownloadTask3()
qui télécharge des données. Pour le simuler, j'ai utilisédelay()
dans ces fonctions. Ces fonctions attendent5 seconds
,8 seconds
et5 seconds
respectivement.Comme nous l'avons utilisé
launch
pour démarrer ces fonctions de suspension,launch
les exécutera séquentiellement (une par une) . Cela signifie que,downloadTask2()
commencerait une foisdownloadTask1()
terminé etdownloadTask3()
ne commencerait qu'une foisdownloadTask2()
terminé.Comme dans la capture d'écran de sortie
Toast
, le temps total d'exécution pour terminer les 3 téléchargements conduirait à 5 secondes + 8 secondes + 5 secondes = 18 secondes aveclaunch
Comme nous l'avons vu, cela
launch
permet l'exécutionsequentially
des 3 tâches. Le temps était venu de terminer toutes les tâches18 seconds
.Si ces tâches sont indépendantes et si elles n'ont pas besoin du résultat de calcul d'une autre tâche, nous pouvons les faire fonctionner
concurrently
. Ils commenceraient en même temps et fonctionneraient simultanément en arrière-plan. Cela peut être fait avecasync
.async
renvoie une instance deDeffered<T>
type, oùT
est le type de données renvoyées par notre fonction de suspension. Par exemple,downloadTask1()
retourneraitDeferred<String>
car String est le type de retour de la fonctiondownloadTask2()
retourneraitDeferred<Int>
car Int est le type de retour de la fonctiondownloadTask3()
retourneraitDeferred<Float>
car Float est le type de retour de la fonctionNous pouvons utiliser l'objet de retour de
async
de typeDeferred<T>
pour obtenir la valeur retournée dansT
type. Cela peut être fait avec unawait()
appel. Vérifiez le code ci-dessous par exempleDe cette façon, nous avons lancé les 3 tâches simultanément. Donc, mon temps d'exécution total pour terminer serait seulement
8 seconds
ce qui est le tempsdownloadTask2()
car c'est la plus grande des 3 tâches. Vous pouvez le voir dans la capture d'écran suivante dansToast message
la source
launch
c'est pour les funs séquentiels , tandis queasync
pour les simultanéslaunch
etasync
vont démarrer de nouvelles coroutines. Vous comparez une seule coroutine sans enfants à une seule coroutine avec 3 enfants. Vous pouvez remplacer chacune desasync
invocations parlaunch
et absolument rien ne changerait en ce qui concerne la concurrence.les deux constructeurs de coroutine, à savoir le lancement et l'asynchrone, sont essentiellement des lambdas avec un récepteur de type CoroutineScope, ce qui signifie que leur bloc interne est compilé en tant que fonction de suspension, par conséquent, ils s'exécutent tous les deux en mode asynchrone ET ils exécuteront tous les deux leur bloc séquentiellement.
La différence entre lancer et asynchrone est qu'ils offrent deux possibilités différentes. Le générateur de lancement renvoie un Job mais la fonction async renverra un objet Deferred. Vous pouvez utiliser launch pour exécuter un bloc dont vous n'attendez pas de valeur renvoyée, c'est-à-dire écrire dans une base de données ou enregistrer un fichier ou traiter quelque chose qui est simplement appelé pour son effet secondaire. D'autre part, async qui retourne un Deferred comme je l'ai dit précédemment renvoie une valeur utile de l'exécution de son bloc, un objet qui enveloppe vos données, vous pouvez donc l'utiliser principalement pour son résultat mais éventuellement aussi pour son effet secondaire. NB: vous pouvez supprimer le différé et récupérer sa valeur à l'aide de la fonction wait, qui bloquera l'exécution de vos instructions jusqu'à ce qu'une valeur soit renvoyée ou qu'une exception soit levée!
les deux coroutine builder (lancement et asynchrone) sont annulables.
quoi de plus?: oui au lancement si une exception est levée dans son bloc, la coroutine est automatiquement annulée et les exceptions sont livrées. D'autre part, si cela se produit avec async, l'exception n'est pas propagée davantage et doit être interceptée / gérée dans l'objet Deferred renvoyé.
plus sur coroutines https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1
la source
lancer renvoie un travail
async renvoie un résultat (tâche différée)
lancer avec join est utilisé pour attendre que le travail soit terminé.
async est utilisé pour calculer certains résultats. Il crée une coroutine et renvoie son résultat futur en tant qu'implémentation de Deferred. La coroutine en cours d'exécution est annulée lorsque le différé résultant est annulé.
Considérez une méthode asynchrone qui renvoie une valeur de chaîne. Si la méthode async est utilisée sans attendre, elle retournera une chaîne Deferred mais si await est utilisé, vous obtiendrez une chaîne comme résultat
La principale différence entre async et launch. Deferred renvoie une valeur particulière de type T après la fin de l'exécution de votre Coroutine, contrairement à Job.
la source
Async vs Launch Async vs Launch Diff Image
lancer / asynchrone aucun résultat
asynchrone pour résultat
la source