Internos de los flujos de Kotlin. Para entender mejor las corrientes, debemos… | de Tushar Saha | diciembre 2022

Para comprender mejor los flujos, debemos revisar las funciones de suspensión y las corrutinas. Una función de suspensión es simple El compilador hace la magia aquí. El compilador simplemente toma el código que parece procedimental y lo convierte en devoluciones de llamada bajo el capó. La continuación es el objeto que realiza un seguimiento de dónde detenerse y dónde continuar. Digamos que tenemos el siguiente código con 2 puntos de suspensión. val a = a()val y = foo(a).await() // punto de suspensión #1b ()val z = bar(a, y).await() // punto de suspensión #2c(z) El compilador genera esto internamente Hay tres estados para este bloque de código:

  • inicial (antes de cada punto de suspensión)
  • después del primer punto de suspensión
  • después del segundo punto de suspensión

clase extiende SuspendLambda<...> { // El estado actual de la máquina de estado int label = 0 // CoroutineA variables locales a = nullY y = nullvoid resumeWith(Object result) { if (label == 0) go to L0if (label == 1) go to L1if (label == 2) ir a L2else throw IllegalStateException()L0:// Se espera que el resultado sea ‘nulo’ en esta calla = a()label = 1result = foo(a). await(this) // ‘this’ se pasa como una continuación if (result == COROUTINE_SUSPENDED) return // return if espera ejecución suspendidaL1:// El código externo reanudó esta rutina y el resultado de .await() pasó y = ( Y ) resultb()label = 2result = bar(a, y).await(this) // ‘this’ se pasa como una continuación if (result == COROUTINE_SUSPENDED) return // return if espera la ejecución del L2:// externo los códigos continuaron con esta rutina y pasaron el resultado de .await()Z z = (Z) resultc(z)label = -1 // No se permiten más pasos return} }El objeto de continuación realiza un seguimiento del estado de la función de suspensión. Actualiza la etiqueta a medida que nos movemos de un punto de suspensión a otro. En otras palabras, el compilador genera el código que rastrea el estado de la función de suspensión en diferentes puntos de suspensión.

  • – para trabajos intensivos en CPU (por ejemplo, ordenar una lista grande)
  • – Esto depende de lo que haya agregado a las dependencias de tiempo de ejecución de su programa (por ejemplo, kotlinx-coroutines-android para el subproceso de interfaz de usuario en Android).
  • – Ejecutar rutinas sin restricciones en cualquier subproceso específico
  • – para trabajos pesados ​​de E/S (por ejemplo, consultas de base de datos de larga duración)

La concurrencia estructurada en las rutinas de Kotlin requiere que los desarrolladores siempre inicien las rutinas en el contexto de CoroutineScope o que especifiquen explícitamente que un alcance se define como una función de extensión en CoroutineScope y toma un CoroutineContext como parámetro, por lo que en realidad necesita dos contextos de rutina (ya que un alcance es solo una referencia está en un contexto). ¿Qué pasa con ellos? Los une con el operador más y crea una unión de conjunto de sus elementos. Se utiliza un flujo para la ilustración. que alguna vez (porque se acaba de forma natural o pasa algo malo). Todas las operaciones en un flujo dentro del mismo bloque de código (y por lo tanto el mismo ámbito de rutina). Detrás de escena, un flujo es solo una interfaz que expone un método para recopilar los valores devueltos: T)}flujo de interfaz {suspender colección divertida (coleccionista: FlowCollector)} Estos son simplemente 2 métodos etiquetados suspender y Si observamos el código compilado, veremos que simplemente usa la función Suspender para crear un objeto de continuación que marca cómo funcionan juntos Flow y Collector.Utiliza la característica Suspender para crear código compilado que es esencialmente secuencial en naturaleza y alcance para controlar el ciclo de vida del flujo. Fuentes: https://kt.academy/article/how-flow-works

Deja una respuesta

Tu dirección de correo electrónico no será publicada.