Flow
Un flow és un flux de dades que pot ser processat de forma asíncrona.
Introducció
Una corutina centrada en simples funcions de suspensió funciona molt bé quan:
-
Necessites fer treball asíncron, però no necessites rebre cap mena de “resultat” d’aquest treball
-
Necessites fer treball asíncron, i esperes un únic objecte que serveix com a resultat
No obstant això, hi ha moltes ocasions en programació on necessites un flux de resultats, no només un únic resultat. Una funció de suspensió ordinària no ofereix això. En canvi, el sistema de corutines de Kotlin ofereix canals i flows per a fluxos de resultats. Dels dos, els flows són l’API principal de streaming per a corutines, encara que els canals tenen alguns usos especialitzats.
Bastant treball asíncron es pot modelar com a operacions sense resultat o d’un sol resultat:
- Transaccions de base de dades
- Crides a serveis web
- Descàrrega o lectura d’un fitxer d’imatge
- I així successivament
Bàsicament, qualsevol cosa que sigui de naturalesa transaccional — on cada resultat és desencadenat per una petició diferent — es pot modelar com una operació sense resultat o d’un sol resultat. Aquests funcionen molt bé amb funcions de suspensió ordinàries.
No obstant això, també és comú tenir una única rutina que necessita retornar una sèrie de resultats al llarg del temps:
- Connexions de xarxa duradores, com WebSockets o XMPP, on el servidor pot enviar contingut sense una nova petició del client
- Lectures de GPS
- Lectures de sensors d’acceleròmetres, termòmetres, etc.
- Dades rebudes de dispositius externs via USB, Bluetooth, etc.
- I així successivament
Alguns entorns o frameworks de programació poden tenir els seus propis fluxos. Per exemple, podem obtenir diversos resultats al llarg del temps de Room (a mesura que canviem el contingut d’una base de dades).
Conceptes bàsics
Crea un projecte “JVM console application” amb Amper
Modifica el fitxer module.yaml:
dependencies:
- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
test-dependencies:
- io.kotest:kotest-assertions-core:5.9.0
- org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2Els flows simples estan representats en forma d’un objecte Flow.
Una manera típica de crear un Flow és utilitzant la funció de nivell superior flow().
flow() és bastant simple: proporciones una expressió lambda, i aquesta expressió crida a emit() per cada element que vols publicar en el flux.
Una manera típica de consumir un Flow és cridar collect() sobre ell. Això pren una altra expressió lambda, i se li passa cada element que el Flow emet al seu flux.
collect() és una funció de suspensió, i per tant necessitem cridar-la des de dins d’una altra funció de suspensió o des d’un constructor de corutines com launch().
Modifica el fitxer main.kt per tal d’imprimir alguns nombres aleatoris:
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlin.random.Random
fun main() = runBlocking {
launch {
randomPercentages(10, 200).collect { println(it) }
println("That's all folks!")
}
println("...and we're off!")
}
fun randomPercentages(count: Int, delayMs: Long) = flow {
for (i in 0 until count) {
delay(delayMs)
emit(Random.nextInt(1, 100))
}
}Aquí, randomPercentages() crea un Flow utilitzant flow(). Fa un bucle un nombre específic de vegades, espera un nombre específic de mil·lisegons en cada passada, i per cada passada emet un nombre aleatori.
Cal destacar:
-
emit()és una funció de suspensió.flow()configura una corutina perquè la puguis utilitzar, així que no t’has de preocupar de fer-ho tu mateix. Però això significa queemit()pot provocar un canvi a una altra corutina, i queemit()podria bloquejar-se durant una estona. -
Quan surts de l’expressió lambda, el flux es considera tancat.
Després, dins d’una corutina llançada, cridem collect() sobre aquest Flow, imprimint cada número. Això ens donarà quelcom com:
...and we're off!
30
84
62
79
19
83
83
6
81
59
That's all folks!Així doncs, el nostre Flow emet objectes, i la nostra funció collect() — que configura un FlowCollector — els rep.
Obtenint un Flow
Les tres maneres principals d’obtenir un Flow són:
- Cridar una funció de nivell superior del sistema de corutines de Kotlin,
- Convertir un Channel a Flow, o
- Obtenir un Flow d’una biblioteca de tercers
flowOf()
flowOf() accepta un nombre variable de paràmetres i els emet un per un. Només has de proporcionar els objectes:
@Test
fun flow_of() = runTest {
flowOf(1, 2, 3).toList() shouldBe listOf(1, 2, 3)
}Estás leyendo una vista previa.
Inicia sesión para leer el artículo completo. Cualquier cuenta abre 4 artículos gratuitos al mes; el alumnado y el profesorado leen las páginas de su curso sin límite.
Iniciar sesión