Módulo 03: Dart Deep Dive

Event Loop

Runtime Memoria

⏱️ Tiempo de lectura: ~8 min 📊 Nivel: Intermedio 🔄 Actualizado: Dic 2025
# 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.

¿Te resultó útil esta lección?