# El Event Loop en Dart
Dart es un lenguaje **single-threaded** (de un solo hilo). Esto significa que ejecuta una operación a la
vez. Sin embargo, puede realizar operaciones asíncronas (como leer un archivo o hacer una petición HTTP)
sin bloquear la ejecución gracias al **Event Loop**.
## ¿Cómo funciona?
Imagina el Event Loop como un bucle infinito que procesa eventos de dos colas:
1. **Microtask Queue**: Tareas de alta prioridad, cortas y urgentes.
2. **Event Queue**: Eventos externos (I/O, timers, gestos, dibujo).
### El Algoritmo del Event Loop
1. Ejecuta el código `main()` síncrono.
2. Si la **Microtask Queue** no está vacía:
- Ejecuta la primera microtask.
- Repite hasta vaciar la cola.
3. Si la **Event Queue** no está vacía:
- Toma el primer evento.
- Ejecuta su manejador (handler).
- Vuelve al paso 2 (revisar microtasks).
4. Si no hay nada más, espera.
## Microtasks vs Events
| Característica | Microtask Queue | Event Queue |
|----------------|-----------------|-------------|
| Prioridad | Alta (se ejecuta antes que el siguiente evento) | Normal |
| Origen | `scheduleMicrotask`, `Future.value`, `Future.sync` | I/O, Timers, Gestos, `Future` (normal) |
| Peligro | Puede bloquear la UI si es infinita | Generalmente seguro |
### Ejemplo Práctico
```dart
import 'dart:async';
void main() {
print('1. Inicio del main');
// Event Queue
Future(() => print('4. Future (Event Queue)'));
// Microtask Queue
scheduleMicrotask(() => print('3. Microtask'));
print('2. Fin del main');
}
// Output:
// 1. Inicio del main
// 2. Fin del main
// 3. Microtask
// 4. Future (Event Queue)
```
## Bloqueando el Event Loop
Como Dart es single-threaded, si ejecutas una tarea pesada (cálculo matemático complejo, procesamiento
de imagen grande) en el hilo principal, **bloquearás el Event Loop**.
```dart
void tareaPesada() {
// ❌ Esto congela la UI por 5 segundos
final stop = DateTime.now().add(Duration(seconds: 5));
while (DateTime.now().isBefore(stop)) {
// Loop infinito por 5 segundos
}
}
```
**Consecuencias en Flutter:**
- La UI se congela (ANR en Android).
- Las animaciones se detienen (Jank).
- Los gestos no responden.
**Solución:** Usa **Isolates** para tareas pesadas de CPU.
## Futures y el Event Loop
Cuando creas un `Future`, estás diciendo: "Pon esta tarea en la Event Queue y avísame cuando termine".
```dart
Future leerArchivo() async {
print('Iniciando lectura...');
// El control vuelve al Event Loop mientras se lee el disco
final contenido = await File('data.txt').readAsString();
// Cuando termina, el Event Loop pone la continuación aquí
print(contenido);
}
```
## ⚠️ Errores Comunes y Soluciones
### Error 1: Microtask Infinita
**Código problemático:**
```dart
void main() {
scheduleMicrotask(() {
print('Microtask');
scheduleMicrotask(() => main()); // ❌ ¡Recursión infinita!
});
}
```
**Síntoma:** App completamente congelada, no responde a ninguna interacción.
**Causa:** La Microtask Queue nunca se vacía porque constantemente se agregan nuevas microtasks.
**Solución:**
```dart
void main() {
int count = 0;
void scheduleLimited() {
if (count < 10) { scheduleMicrotask(() { print('Microtask $count'); count++; scheduleLimited(); });
} } scheduleLimited(); // ✅ Limitado a 10 iteraciones } ``` **Cómo detectar:** DevTools →
Performance tab → buscar frames que toman>16ms.
---
### Error 2: Blocking I/O en Main Thread
**Código problemático:**
```dart
String readFile() {
return File('large.txt').readAsStringSync(); // ❌ Sync!
}
void main() {
final content = readFile(); // UI congelada durante lectura
print(content);
}
```
**Síntoma:** UI congelada durante operaciones de I/O.
**Causa:** Operación síncrona bloquea el Event Loop.
**Solución:**
```dart
Future readFile() async {
return await File('large.txt').readAsString(); // ✅ Async
}
void main() async {
final content = await readFile(); // Event Loop puede procesar otros eventos
print(content);
}
```
---
### Error 3: Tarea Pesada de CPU en Main Thread
**Código problemático:**
```dart
List processLargeList(List data) {
// ❌ Procesamiento pesado en main thread
return data.map((n) => n * n * n).toList();
}
void main() {
final bigList = List.generate(10000000, (i) => i);
final result = processLargeList(bigList); // UI congelada
}
```
**Síntoma:** Animaciones se detienen, gestos no responden (Jank).
**Solución:**
```dart
import 'dart:isolate';
List _processInIsolate(List data) {
return data.map((n) => n * n * n).toList();
}
void main() async {
final bigList = List.generate(10000000, (i) => i);
// ✅ Usar compute para ejecutar en isolate separado
final result = await compute(_processInIsolate, bigList);
}
```
## Conclusión
- Dart ejecuta código en un solo hilo.
- El Event Loop coordina la ejecución asíncrona.
- Las **Microtasks** tienen prioridad sobre los **Events**.
- Nunca bloquees el hilo principal con tareas pesadas de CPU; usa Isolates.
## 📖 Recursos Adicionales
### 📄 Artículos Recomendados
- [Dart Asynchronous Programming](https://dart.dev/codelabs/async-await) -
Official Dart Codelab
- [Understanding the Event
Loop](https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a)
- Medium
- [Flutter Performance Best
Practices](https://docs.flutter.dev/perf/best-practices) - Flutter Docs
### 🎥 Videos
- [Isolates and Event Loops -
Flutter](https://www.youtube.com/watch?v=vl_AaCgudcY) - Flutter Team
- [Dart Async Programming](https://www.youtube.com/watch?v=SmTCmDMi4BY) -
Google Developers
### 💻 Repositorios de Ejemplo
-
[dart-samples/async](https://github.com/dart-lang/samples/tree/master/async_await)
- Official Dart Samples
- [flutter-event-loop-demo](https://github.com/flutter/samples) - Flutter
Samples
### 💬 Comunidades
- [r/dartlang](https://reddit.com/r/dartlang) - Reddit Dart Community
- [Dart Discord](https://discord.gg/Qt6DgfAWWx) - Official Dart Discord
- [Stack Overflow - dart
tag](https://stackoverflow.com/questions/tagged/dart)
### 📚 Libros
- "Dart Apprentice" - raywenderlich.com
- "Flutter Complete Reference" - Alberto Miola
Este apartado profundiza en los conceptos clave, proporcionando ejemplos prácticos y mejores prácticas para su aplicación en proyectos reales.
Al comprender estos detalles, podrás diseñar soluciones más robustas, mantenibles y escalables en tus aplicaciones Flutter y Dart.