En la kotlinx.coroutines
biblioteca, puede comenzar una nueva rutina utilizando launch
(con join
) o async
(con await
). ¿Cuál es la diferencia entre ellos?
fuente
En la kotlinx.coroutines
biblioteca, puede comenzar una nueva rutina utilizando launch
(con join
) o async
(con await
). ¿Cuál es la diferencia entre ellos?
launch
Se utiliza para disparar y olvidar la corutina . Es como comenzar un nuevo hilo. Si el código dentro del launch
termina con 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 utiliza 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 de Deferred
y debe usarlo await
. Una excepción no detectada dentro del async
código se almacena dentro del resultado Deferred
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 .
Encuentro útil esta guía https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md . Citaré las partes esenciales
🦄 corutina
Por lo tanto, puede pensar en la rutina como algo que gestiona el hilo de una manera muy eficiente.
🐤 lanzamiento
Entonces
launch
comienza un hilo de fondo, hace algo y devuelve un token inmediatamente comoJob
. Puede invocarjoin
estoJob
para bloquear hasta que estelaunch
hilo se complete🦆 asíncrono
Entonces
async
comienza un hilo de fondo, hace algo y devuelve un token inmediatamente comoDeferred
.Entonces
Deferred
es en realidad unJob
. Ver https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html🦋 async está ansioso por defecto
fuente
launch
yasync
se utilizan para comenzar nuevas corutinas. Pero, los ejecutan de manera diferente.Me gustaría mostrar un ejemplo muy básico que te ayudará a entender la diferencia muy fácilmente.
En este ejemplo, mi código está descargando 3 datos al hacer clic en el
btnCount
botón y mostrandopgBar
la barra de progreso hasta que se complete toda la descarga. Hay 3suspend
funcionesdownloadTask1()
,downloadTask2()
ydownloadTask3()
que descarga datos. Para simularlo, lo he usadodelay()
en estas funciones. Estas funciones espera a5 seconds
,8 seconds
y5 seconds
respectivamente.Como hemos usado
launch
para iniciar estas funciones de suspensión, laslaunch
ejecutaremos secuencialmente (una por una) . Esto significa quedownloadTask2()
comenzaría después dedownloadTask1()
completarse ydownloadTask3()
comenzaría solo después dedownloadTask2()
completarse.Como en la captura de pantalla de salida
Toast
, el tiempo total de ejecución para completar las 3 descargas llevaría a 5 segundos + 8 segundos + 5 segundos = 18 segundos conlaunch
Como vimos, eso
launch
hace que la ejecuciónsequentially
de las 3 tareas. El momento para completar todas las tareas fue18 seconds
.Si esas tareas son independientes y no necesitan el resultado de cálculo de otra tarea, podemos hacer que se ejecuten
concurrently
. Comenzarían al mismo tiempo y se ejecutarían simultáneamente en segundo plano. Esto se puede hacer conasync
.async
devuelve una instancia deDeffered<T>
tipo, dondeT
es el tipo de datos que devuelve nuestra función de suspensión. Por ejemplo,downloadTask1()
volveríaDeferred<String>
como String es el tipo de función de retornodownloadTask2()
volveríaDeferred<Int>
como Int es el tipo de función de retornodownloadTask3()
regresaríaDeferred<Float>
como Float es el tipo de función de retornoPodemos usar el objeto de devolución from
async
of typeDeferred<T>
para obtener el valor devuelto enT
type. Eso se puede hacer conawait()
llamada. Verifique el siguiente código, por ejemploDe esta manera, hemos lanzado las 3 tareas al mismo tiempo. Entonces, mi tiempo total de ejecución para completar sería solo
8 seconds
el tiempo necesario,downloadTask2()
ya que es la mayor de las 3 tareas. Puedes ver esto en la siguiente captura de pantalla enToast message
fuente
launch
es para diversiones secuenciales , mientras queasync
para concurrenteslaunch
yasync
comenzarán nuevas corutinas. Usted está comparando una única corutina sin hijos con una única con 3 niños. Puede reemplazar cada una de lasasync
invocacioneslaunch
y absolutamente nada cambiaría con respecto a la concurrencia.ambos constructores de coroutine, es decir, launch y async, son básicamente lambdas con un receptor de tipo CoroutineScope, lo que significa que su bloque interno se compila como una función de suspensión, por lo tanto, ambos se ejecutan en modo asíncrono Y ambos ejecutarán su bloque secuencialmente.
La diferencia entre el lanzamiento y el asíncrono es que permiten dos posibilidades diferentes. El generador de inicio devuelve un trabajo, sin embargo, la función asíncrona devolverá un objeto diferido. Puede usar el lanzamiento para ejecutar un bloque del que no espera ningún valor devuelto, es decir, escribir en una base de datos o guardar un archivo o procesar algo que básicamente solo llama su efecto secundario. Por otro lado, async que devuelve un diferido como dije anteriormente devuelve un valor útil de la ejecución de su bloque, un objeto que envuelve sus datos, por lo que puede usarlo principalmente para su resultado, pero posiblemente también para su efecto secundario. NB: puede quitar el diferido y obtener su valor utilizando la función esperar, que bloqueará la ejecución de sus declaraciones hasta que se devuelva un valor o se generen excepciones.
Ambos creadores de rutina (lanzamiento y asíncrono) son cancelables.
¿algo más ?: sí con el lanzamiento si se lanza una excepción dentro de su bloque, la rutina se cancela automáticamente y se entregan las excepciones. Por otro lado, si eso sucede con asíncrono, la excepción no se propaga más y debe capturarse / manejarse dentro del objeto diferido devuelto.
más sobre las rutinas https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1
fuente
lanzamiento devuelve un trabajo
async devuelve un resultado (trabajo diferido)
launch with join se usa para esperar hasta que el trabajo termine. Simplemente suspende la rutina que llama a join (), dejando el hilo actual libre para realizar otro trabajo (como ejecutar otra rutina) mientras tanto.
async se usa para calcular algunos resultados. Crea una rutina y devuelve su resultado futuro como una implementación de Diferido. La rutina en ejecución se cancela cuando se cancela el aplazamiento resultante.
Considere un método asíncrono que devuelve un valor de cadena. Si el método asíncrono se usa sin esperar, devolverá una cadena diferida, pero si se usa esperar, obtendrá una cadena como resultado
La diferencia clave entre asíncrono y lanzamiento. Diferido devuelve un valor particular de tipo T después de que su Coroutine termina de ejecutarse, mientras que Job no lo hace.
fuente
Async vs Launch Async vs Launch Diff Image
lanzamiento / asíncrono sin resultado
asíncrono para el resultado
fuente