← Dart EspañolChapter 11 of 13

Programacion Asincrona

## Objetivos de Aprendizaje - Comprender conceptos de programacion asincrona - Dominar Future y async/await - Trabajar con Streams - Manejar errores en codigo asincrono ## Por Que Asincrono? ### El Problema ```dart // Sincrono - bloquea hasta completar void main() { print('Antes'); var data = fetchData(); // Bloquea por 5 segundos print(data); print('Despues'); } ``` ### La Solucion ```dart // Asincrono - no bloquea void main() async { print('Antes'); var data = await fetchData(); // No bloquea print(data); print('Despues'); } ``` ## Future ### Concepto Basico ```dart void main() { // simular operacion asincrona Future fetchData() { return Future.delayed(Duration(seconds: 2), () { return 'Datos cargados'; }); } print('Antes'); fetchData().then((data) { print(data); // Datos cargados }); print('Despues'); // Se imprime antes que los datos (no bloquea) } ``` ### Estados de Future 1. **Incompleto**: Operacion en progreso 2. **Completado con valor**: Exito 3. **Completado con error**: Falla ## async y await ### Sintaxis Basica ```dart Future fetchUser() async { // Simular retraso de red await Future.delayed(Duration(seconds: 1)); return 'Alice'; } void main() async { print('Obteniendo...'); String user = await fetchUser(); print('Usuario: $user'); } ``` ### Reglas de Funciones async ```dart // funcion async siempre devuelve Future Future addOne(int n) async { await Future.delayed(Duration(milliseconds: 100)); return n + 1; } // void async - solo para efectos secundarios Future process() async { await Future.delayed(Duration(seconds: 1)); print('Hecho'); } ``` ### Multiples awaits ```dart Future loadData() async { print('Cargando...'); var user = await fetchUser(); var posts = await fetchPosts(user); print('Usuario: $user'); print('Publicaciones: $posts'); } ``` ## Manejo de Errores ### Try-Catch ```dart Future fetchData() async { try { var result = await riskyOperation(); print('Exito: $result'); } catch (e) { print('Error: $e'); } } Future riskyOperation() async { await Future.delayed(Duration(seconds: 1)); throw Exception('Fallo!'); } ``` ### Capturar Errores Especificos ```dart Future process() async { try { await fetchData(); } on NetworkException { print('Error de red'); } on ServerException catch (e) { print('Error de servidor: $e'); } catch (e, stack) { print('Inesperado: $e'); print('Stack: $stack'); } } class NetworkException implements Exception {} class ServerException implements Exception { final String message; ServerException(this.message); } ``` ### Finally ```dart Future process() async { try { await fetchData(); } catch (e) { print('Error: $e'); } finally { // Siempre se ejecuta await cleanup(); } } ``` ## Metodos de Future ### then ```dart Future fetchNumber() async { return 42; } void main() { fetchNumber() .then((n) => n * 2) .then((n) => print('Resultado: $n')); // Resultado: 84 } ``` ### catchError ```dart Future fetchNumber() async { throw Exception('Error'); } void main() { fetchNumber() .catchError((e) => print('Capturado: $e')) .then((n) => print('Numero: $n')); // Capturado: Exception: Error } ``` ### whenComplete ```dart Future process() async { await fetchData() .whenComplete(() => print('Limpieza completada')); } ``` ### wait ```dart Future main() async { var futures = [ fetchUser(1), fetchUser(2), fetchUser(3), ]; var results = await Future.wait(futures); print('Todos los usuarios: $results'); } ``` ## Streams ### Basicos de Stream ```dart Stream countStream() async* { for (int i = 1; i <= 5; i++) { await Future.delayed(Duration(seconds: 1)); yield i; } } void main() async { await for (var value in countStream()) { print(value); // 1, 2, 3, 4, 5 (cada segundo) } print('Hecho'); } ``` ### Metodos de Stream ```dart void main() { var stream = Stream.fromIterable([1, 2, 3, 4, 5]); // listen stream.listen((value) { print('Recibido: $value'); }); // map stream.map((n) => n * 2); // where stream.where((n) => n % 2 == 0); // take stream.take(3); } ``` ### Streams de Suscripcion Unica ```dart Stream countStream() async* { for (int i = 1; i <= 5; i++) { yield i; } } void main() async { var stream = countStream(); // Solo puede escucharse una vez stream.listen(print); // stream.listen(print); // Error: ya se esta escuchando } ``` ### Streams de Difusion ```dart class EventBus { final _controller = StreamController.broadcast(); Stream get stream => _controller.stream; void emit(String event) { _controller.add(event); } void dispose() { _controller.close(); } } void main() { var bus = EventBus(); bus.stream.listen((e) => print('Escuchador 1: $e')); bus.stream.listen((e) => print('Escuchador 2: $e')); bus.emit('Hola'); // Ambos escuchadores reciben bus.dispose(); } ``` ## Patrones Asincronos ### FutureBuilder (Flutter) ```dart // Ejemplo Flutter FutureBuilder( future: fetchData(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return CircularProgressIndicator(); } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else { return Text('Datos: ${snapshot.data}'); } }, ) ``` ### StreamBuilder (Flutter) ```dart // Ejemplo Flutter StreamBuilder( stream: countStream(), builder: (context, snapshot) { if (!snapshot.hasData) { return CircularProgressIndicator(); } return Text('Conteo: ${snapshot.data}'); }, ) ``` ## Operaciones Asincronas Comunes ### timeout ```dart Future fetchData() async { return Future.delayed(Duration(seconds: 5), () => 'Datos'); } void main() async { try { var result = await fetchData().timeout( Duration(seconds: 2), onTimeout: () => 'Valor por defecto de timeout', ); print(result); // Valor por defecto de timeout } catch (e) { print('Error: $e'); } } ``` ### retry ```dart Future fetchWithRetry() async { for (int i = 0; i < 3; i++) { try { return await fetchData(); } catch (e) { if (i == 2) rethrow; await Future.delayed(Duration(seconds: 1)); } } throw Exception('Fallo'); } ``` ## Async vs Sync | Aspecto | Async | Sync | |--------|-------|------| | Bloqueante | No | Si | | Devuelve | Future | Valor | | Palabra clave | async/await | Ninguna | | Error | try/catch | try/catch | | Caso de uso | I/O, red | Computacion | ## Resumen - Future: representa un valor disponible en algun momento posterior - `async` hace que la funcion devuelva Future - `await` pausa hasta que Future complete - Streams: secuencia de eventos asincronos - `async*` produce multiples valores desde stream - `listen` subscribe a streams - Manejar errores con try/catch - `StreamController` crea streams programaticamente

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →