Aller au contenu principal

Module Dart.8 – Asynchrone

Objectif

Maîtriser la programmation asynchrone Dart : Future, async/await, Stream pour gérer les opérations non-bloquantes efficacement.

Théorie

Future

Un Future représente une valeur qui sera disponible dans le futur.

Création

Future<String> chargerDonnees() async {
await Future.delayed(Duration(seconds: 1));
return 'Données chargées';
}

Utilisation avec then

chargerDonnees().then((donnees) {
print(donnees);
}).catchError((erreur) {
print('Erreur : $erreur');
});

Future constructeurs

// Future résolu immédiatement
Future.value('Valeur');

// Future rejeté
Future.error('Erreur');

// Future qui attend
Future.delayed(Duration(seconds: 1), () => 'Résultat');

async/await

Syntaxe moderne pour gérer les Futures de manière synchrone.

async

Une fonction async retourne toujours un Future.

Future<String> chargerDonnees() async {
return 'Données chargées';
}

// Équivalent à :
Future<String> chargerDonnees() {
return Future.value('Données chargées');
}

await

await pause l'exécution jusqu'à ce que le Future soit résolu.

Future<void> processus() async {
try {
String donnees = await chargerDonnees();
print(donnees);

String traitees = await traiterDonnees(donnees);
print(traitees);
} catch (e) {
print('Erreur : $e');
}
}

Avantages :

  • Code plus lisible (semble synchrone)
  • Gestion d'erreurs avec try/catch
  • Pas de callback hell

await avec plusieurs Futures

Séquentiel :

var donnees1 = await charger1();
var donnees2 = await charger2();
// Total : temps1 + temps2

Parallèle :

var futures = await Future.wait([
charger1(),
charger2(),
charger3()
]);
// Total : max(temps1, temps2, temps3)

Stream

Un Stream représente une séquence asynchrone d'événements.

Création

Stream<int> compter() async* {
for (int i = 0; i < 10; i++) {
yield i;
await Future.delayed(Duration(seconds: 1));
}
}

async :* Fonction génératrice asynchrone yield : Émet une valeur dans le stream

Utilisation

await for (int n in compter()) {
print(n);
}

Méthodes de Stream :

stream.listen((valeur) {
print(valeur);
});

stream.map((n) => n * 2).listen((valeur) {
print(valeur);
});

stream.where((n) => n % 2 == 0).listen((valeur) {
print(valeur);
});

Gestion d'erreurs asynchrones

Avec async/await

Future<void> operation() async {
try {
var resultat = await maFuture();
print(resultat);
} catch (e) {
print('Erreur : $e');
}
}

Avec then/catchError

maFuture()
.then((resultat) {
print(resultat);
})
.catchError((erreur) {
print('Erreur : $erreur');
});

Cas d'usage

Requêtes HTTP

import 'package:http/http.dart' as http;

Future<String> chargerAPI() async {
try {
var response = await http.get(Uri.parse('https://api.exemple.com/data'));
if (response.statusCode == 200) {
return response.body;
} else {
throw Exception('Erreur HTTP ${response.statusCode}');
}
} catch (e) {
throw Exception('Erreur : $e');
}
}

Fichiers

import 'dart:io';

Future<String> lireFichier(String chemin) async {
try {
var fichier = File(chemin);
return await fichier.readAsString();
} catch (e) {
throw Exception('Impossible de lire le fichier : $e');
}
}

Exercice

  1. Future

    • Créez des Futures
    • Utilisez then/catchError
    • Testez les constructeurs
  2. async/await

    • Convertissez des callbacks en async/await
    • Gèrez les erreurs avec try/catch
    • Testez await avec plusieurs Futures
  3. Stream

    • Créez des streams
    • Utilisez async* et yield
    • Parcourez avec await for
  4. Parallélisme

    • Chargez plusieurs données en parallèle
    • Comparez séquentiel vs parallèle
    • Utilisez Future.wait
  5. Cas pratiques

    • Simulez des requêtes HTTP
    • Gèrez les fichiers asynchrones
    • Créez des streams de données

Quiz

  1. Que retourne une fonction async ?

    • La valeur directement
    • Un Future
    • Un Stream
  2. Que fait await ?

    • Crée un Future
    • Attend la résolution d'un Future
    • Annule un Future
  3. Quelle est la différence entre Future et Stream ?

    • Aucune différence
    • Future = une valeur, Stream = séquence
    • Stream est plus rapide
  4. Que fait async* ?

    • Crée un Future
    • Crée une fonction génératrice asynchrone
    • Optimise le code
  5. Comment charger plusieurs Futures en parallèle ?

    • await future1; await future2;
    • await Future.wait([future1, future2])
    • future1.then(() => future2)

Mini défi

Mission : Créer un système de chargement asynchrone

Créez un système qui charge et traite des données :

Fonctionnalités :

  1. Simulation de chargement (Future.delayed)
  2. Chargement séquentiel vs parallèle
  3. Stream de données
  4. Gestion d'erreurs complète
  5. Comparaison des performances

Critères :

  • ✅ Utilisation de Future et async/await
  • ✅ Streams créés et utilisés
  • ✅ Gestion d'erreurs appropriée
  • ✅ Code propre et documenté

Objectif : Maîtriser la programmation asynchrone Dart pour créer des applications réactives.


Validation : Vous pouvez passer au module suivant quand vous maîtrisez Future, async/await et Stream.