Middle
Qu'est-ce qu'un Completer en Dart et comment peut-il être utilisé dans le développement Flutter?
sobes.tech IA
Réponse de l'IA
Completer est une classe dans la bibliothèque dart:async qui permet de créer un Future et de le compléter plus tard avec une valeur ou une erreur. Il est utile lorsque une opération asynchrone ne retourne pas directement un Future, mais peut être notifiée de sa finalisation.
import 'dart:async';
void main() async {
final completer = Completer<String>(); // Créer un Completer pour Future<String>
// Simulation d'une opération asynchrone
Future.delayed(Duration(seconds: 2), () {
// Compléter le Future avec une valeur réussie
completer.complete("Opération terminée avec succès!");
// completer.completeError(StateError("Quelque chose a mal tourné!")); // Ou avec une erreur
});
print("En attente de la fin de l'opération...");
try {
// Obtenir le Future du Completer et attendre sa complétion
final result = await completer.future;
print("Résultat : $result");
} catch (e) {
print("Une erreur est survenue : $e");
}
}
Dans Flutter, Completer est souvent utilisé pour :
- Intégration avec des API natives : Lorsqu'un code natif appelle un callback à la fin d'une opération, on peut utiliser
Completerpour le convertir en Future en Dart. - Implémentation d'opérations asynchrones personnalisées : Si vous souhaitez créer une fonction asynchrone qui n'utilise pas d'API existantes retournant un Future.
- Interaction entre isolates : Pour signaler la fin du travail dans un autre isolate.
Exemple d'utilisation en Flutter avec une API native (hypothétique) :
import 'dart:async';
import 'package:flutter/services.dart';
class NativeService {
static const platform = MethodChannel('com.example/native_service');
Future<String> performNativeOperation() async {
final completer = Completer<String>();
try {
final result = await platform.invokeMethod('startOperation');
// Il est supposé que le code natif appellera la méthode 'operationCompleted'
// avec le résultat ou l'erreur, et nous écoutons ces appels.
platform.setMethodCallHandler((call) async {
if (call.method == 'operationCompleted') {
if (call.arguments is String) {
completer.complete(call.arguments as String);
} else if (call.arguments is PlatformException) {
completer.completeError(call.arguments as PlatformException);
} else {
completer.completeError(StateError("Résultat natif inconnu"));
}
// Supprimer le handler si plus nécessaire
platform.setMethodCallHandler(null);
}
return true; // Indique que l'appel a été traité
});
} on PlatformException catch (e) {
completer.completeError(e);
}
return completer.future; // Retourne le Future qui sera complété plus tard
}
}
// Dans un widget ou autre :
// final service = NativeService();
// try {
// final nativeResult = await service.performNativeOperation();
// print("Résultat natif : $nativeResult");
// } catch (e) {
// print("Erreur lors de l'opération native : $e");
// }