asynchronous - lib - kotlin launch
¿Cuál es la diferencia entre lanzar/unir y asíncrono/esperar en las rutinas de Kotlin? (2)
Encuentro útil esta guía https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md . Citaré las partes esenciales
🦄 corutina
Esencialmente, las corutinas son hilos livianos.
Por lo tanto, puede pensar en la rutina como algo que gestiona el hilo de una manera muy eficiente.
🐤 lanzamiento
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
}
Por lo tanto, el
launch
inicia un subproceso en segundo plano, hace algo y devuelve un token inmediatamente como
Job
.
Puede llamar a
join
en este
Job
para bloquear hasta que se complete este hilo de
launch
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
}
🦆 asíncrono
Conceptualmente, async es como el lanzamiento. Comienza una rutina separada que es un hilo liviano que funciona simultáneamente con todas las otras rutinas. La diferencia es que el lanzamiento devuelve un Trabajo y no tiene ningún valor resultante, mientras que async devuelve un Diferido, un futuro ligero y no bloqueante que representa una promesa de proporcionar un resultado más adelante.
Por lo tanto,
async
inicia un subproceso en segundo plano, hace algo y devuelve un token inmediatamente como
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")
}
Puede usar .await () en un valor diferido para obtener su resultado final, pero diferido también es un trabajo, por lo que puede cancelarlo si es necesario.
Así que
Deferred
es en realidad un
Job
.
Ver
Deferred
interface Deferred<out T> : Job (source)
🦋 async está ansioso por defecto
Hay una opción de pereza para sincronizar utilizando un parámetro de inicio opcional con un valor de CoroutineStart.LAZY. Inicia la rutina solo cuando alguien espera su resultado o si se invoca una función de inicio.
En la biblioteca
kotlinx.coroutines
puede iniciar una nueva corutina usando
launch
(con
join
) o
async
(con
await
).
¿Cuál es la diferencia entre ellos?
-
launch
se utiliza para disparar y olvidar la rutina . Es como comenzar un nuevo hilo. Si el código dentro dellaunch
termina con una excepción, entonces se trata como una excepción no capturada en un hilo, generalmente impreso en stderr en aplicaciones JVM de back-end y bloquea las aplicaciones de Android.join
se usa para esperar la finalización de la rutina lanzada y no propaga su excepción. Sin embargo, una rutina infantil caída también cancela a su padre con la excepción correspondiente. -
async
se usa para iniciar una rutina que calcula algún resultado . El resultado está representado por una instancia deDeferred
y debe usarawait
en él. Una excepción no detectada dentro del códigoasync
se almacena dentro delDeferred
resultante y no se entrega en ningún otro lugar, se eliminará silenciosamente a menos que se procese. NO DEBE olvidarse de la rutina que comenzó con async .