Dans la bibliothèque kotlinx.coroutines
, vous pouvez démarrer un nouveau répertoire en utilisant launch
(avec join
) ou async
(avec await
). Quelle est la différence entre eux?
launch
est utilisé pour tirer et oublier la routine . C'est comme commencer un nouveau fil. Si le code à l'intérieur de launch
se termine avec une exception, il est traité comme une exception ncaught dans un thread - généralement imprimé sur stderr dans les applications JVM dorsales et bloque les applications Android. join
est utilisé pour attendre l'achèvement de la coroutine lancée et il ne propage pas son exception. Cependant, une coroutine bloquée enfant annule également son parent avec l'exception correspondante.
async
est utilisé pour démarrer un coroutine qui calcule un résultat . Le résultat est représenté par une instance de Deferred
et vous devez utiliser await
dessus. Une exception non interceptée dans le code async
est stockée dans le Deferred
résultant et n'est livrée nulle part ailleurs. Elle sera supprimée en mode silencieux sauf si elle est 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 vais citer les parties essentielles
???? coroutine
Les coroutines sont essentiellement des fils légers.
Ainsi, vous pouvez penser à la coroutine comme à quelque chose qui gère le fil de manière très efficace.
???? lance
fun main(args: Array<String>) {
launch { // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}
Donc, launch
démarre un fil d’arrière-plan, fait quelque chose et renvoie immédiatement un jeton sous la forme Job
. Vous pouvez appeler join
sur ce Job
pour bloquer jusqu'à ce que ce thread launch
se termine
fun main(args: Array<String>) = runBlocking<Unit> {
val job = launch { // launch new coroutine and keep a reference to its Job
delay(1000L)
println("World!")
}
println("Hello,")
job.join() // wait until child coroutine completes
}
???? asynchrone
Conceptuellement, async est comme un lancement. Il commence une coroutine séparée qui est un fil léger qui fonctionne en même temps que toutes les autres coroutines. La différence est que launch renvoie un travail et ne génère aucune valeur résultante, alors que async renvoie un différé - un avenir léger non bloquant qui représente une promesse de fournir un résultat plus tard.
Donc, async
démarre un fil d’arrière-plan, fait quelque chose et renvoie immédiatement un jeton sous la forme Deferred
.
fun main(args: Array<String>) = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
}
Vous pouvez utiliser .await () sur une valeur différée pour obtenir son résultat éventuel, mais différé est également un travail, vous pouvez donc l'annuler si nécessaire.
Donc, Deferred
est en fait un Job
. Voir https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html
interface Deferred<out T> : Job (source)
???? async est impatient par défaut
Il existe une option de paresse à asynchroniser à l'aide d'un paramètre de démarrage facultatif avec une valeur de CoroutineStart.LAZY. Il ne commence la coroutine que lorsque le résultat est attendu par certains ou si une fonction de démarrage est appelée.