Middle
Czym jest Completer w Dart i jak można go używać w rozwoju Flutter?
sobes.tech AI
Odpowiedź od AI
Completer to klasa w bibliotece dart:async, która pozwala na utworzenie Future i późniejsze jego ukończenie z wartością lub błędem. Jest przydatny, gdy operacja asynchroniczna nie zwraca bezpośrednio Future, ale można ją powiadomić o jej zakończeniu.
import 'dart:async';
void main() async {
final completer = Completer<String>(); // Tworzymy Completer dla Future<String>
// Symulacja operacji asynchronicznej
Future.delayed(Duration(seconds: 2), () {
// Ukończ Future z wartością sukcesu
completer.complete("Operacja zakończona pomyślnie!");
// completer.completeError(StateError("Coś poszło nie tak!")); // Lub z błędem
});
print("Oczekiwanie na zakończenie operacji...");
try {
// Uzyskaj Future z Completer i poczekaj na jego zakończenie
final result = await completer.future;
print("Wynik: $result");
} catch (e) {
print("Wystąpił błąd: $e");
}
}
W Flutter Completer jest często używany do:
- Integracji z natywnymi API: Gdy natywny kod wywołuje callback po zakończeniu operacji, można użyć
Completerdo przekształcenia tego w Future w Dart. - Implementacji własnych operacji asynchronicznych: Jeśli chcesz utworzyć funkcję asynchroniczną, która nie korzysta z istniejących API zwracających Future.
- Interakcji między izolami: Do sygnalizacji zakończenia pracy w innym izolatcie.
Przykład użycia w Flutter z hipotetycznym API natywnym:
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');
// Zakłada się, że kod natywny wywoła metodę 'operationCompleted'
// z wynikiem lub błędem, i nasłuchujemy te wywołania.
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("Nieznany wynik operacji natywnej"));
}
// Usunięcie obsługi, jeśli nie jest już potrzebne
platform.setMethodCallHandler(null);
}
return true; // Zaznacza, że wywołanie zostało obsłużone
});
} on PlatformException catch (e) {
completer.completeError(e);
}
return completer.future; // Zwraca Future, które zostanie ukończone później
}
}
// W widżecie lub innym miejscu:
// final service = NativeService();
// try {
// final nativeResult = await service.performNativeOperation();
// print("Wynik natywny: $nativeResult");
// } catch (e) {
// print("Błąd operacji natywnej: $e");
// }