runblocking lib kotlinx experimental enable coroutines asynchronous kotlin coroutine kotlinx.coroutines kotlin-coroutines

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 del launch 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 de Deferred y debe usar await en él. Una excepción no detectada dentro del código async se almacena dentro del Deferred 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 .