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
-
Future
- Créez des Futures
- Utilisez then/catchError
- Testez les constructeurs
-
async/await
- Convertissez des callbacks en async/await
- Gèrez les erreurs avec try/catch
- Testez await avec plusieurs Futures
-
Stream
- Créez des streams
- Utilisez async* et yield
- Parcourez avec await for
-
Parallélisme
- Chargez plusieurs données en parallèle
- Comparez séquentiel vs parallèle
- Utilisez Future.wait
-
Cas pratiques
- Simulez des requêtes HTTP
- Gèrez les fichiers asynchrones
- Créez des streams de données
Quiz
-
Que retourne une fonction async ?
- La valeur directement
- Un Future
- Un Stream
-
Que fait await ?
- Crée un Future
- Attend la résolution d'un Future
- Annule un Future
-
Quelle est la différence entre Future et Stream ?
- Aucune différence
- Future = une valeur, Stream = séquence
- Stream est plus rapide
-
Que fait async* ?
- Crée un Future
- Crée une fonction génératrice asynchrone
- Optimise le code
-
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 :
- Simulation de chargement (Future.delayed)
- Chargement séquentiel vs parallèle
- Stream de données
- Gestion d'erreurs complète
- 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.