## Introducción al FLOW
Como hemos visto en la corrutina hacemos llamadas a funciones asíncronas y estas se interrumpen o vuelven a ejecutarse, pero no son reactivas, o sea, no podemos hacer que lo que haga una dependa de las demás.
Flow y corrutinas son dos conceptos importantes en Kotlin para trabajar con programación asíncrona. Les pongo un resumen de funciones para que entiendan que son complementarios pero no son lo mismo:
### Corrutinas:
- Las corrutinas son una forma de manejar la concurrencia y la asincronía en Kotlin.
- Permiten ejecutar tareas de manera no bloqueante en un hilo de ejecución.
- Las funciones suspendidas (marcadas con suspend) son la base de las corrutinas.
- Pueden devolver un solo valor (como una función suspendida normal).
- Son secuenciales por defecto, lo que significa que las operaciones se ejecutan en el mismo hilo de la coroutine1.
- Son ideales para tareas como llamadas a API, operaciones de red y bases de datos.
### Flow:
- Flow es una abstracción construida sobre las corrutinas.
- Proporciona un flujo de datos secuencial que puede emitir múltiples valores a lo largo del tiempo.
- Es “en frío”, lo que significa que los elementos se producen y emiten bajo demanda, no inmediatamente al crearse la fuente.
- Los flujos son útiles para recibir actualizaciones en tiempo real, como datos de una base de datos o eventos de sensores.
Los flujos se componen de tres partes:
- Creación del flujo de datos: Se crea un flujo utilizando funciones como flow { ... }.
- Operadores intermedios: Transforman o filtran los elementos del flujo.
- Operadores terminales: Consumen los elementos del flujo (por ejemplo, collect, toList, etc.).
Pueden manejar múltiples valores y son más flexibles que las funciones suspendidas.
En resumen, las corrutinas son la base para trabajar con asincronía, mientras que los flujos son una forma más avanzada de manejar flujos de datos secuenciales. Ambos se complementan entre sí en el ecosistema de Kotlin.
Usaremos FLow sobre todo cuando sean aplicaciones en tiempo real, con valores que necesiten cambiar en todo momento, aplicaciones sobre el clima, la bolsa, controladores de sensores,.. en general cambios que estén cambiando constantemente en el servidor y tenemos que recibir la información en todo momento.
Imaginemos que a la lista anterior se le agregaran 10 elementos, para mostrar el cambio necesitaríamos un botón de actualizar o algo parecido, como ves...no es lo normal.
Lo primero que haremos será en el ItemsViewModel generar una variable privada _lista que será del tipo MutableStateFlow
```
private val _lista: MutableStateFlow<List<ItemsModel>> = MutableStateFlow(emptyList())
```
Y como no vamos a hacer un cambio real, añadimos esta line a a llamarApi
```
_lista.value=result
```
En el composable ItemsView no podemos llamar a nuestra lista directamente, la tendremos que llamar con el collectAsState
```
@Composable
fun ItemsView(viewModel: ItemsViewModel){
// val itemList= viewModel.itemList
val lista by viewModel.lista.collectAsState()
LaunchedEffect(Unit){
viewModel.fetchData()
}
Column {
if (viewModel.isLoading){
CircularProgressIndicator()
}else {
LazyColumn{
items(lista){
item ->
Text(text = item.name)
}
}
}
}
}
```
Va a parecer que es lo mismo, la diferencia es que en este caso si hubiera cambios en la base de datos, se mostraría sin necesidad de hacer nada por nuestra parte, como lo vamos a usar posteriormente esto sirve de pequeña introducción.