Middle
Co je to Completer v Dart a jak jej lze použít ve vývoji Flutter?
sobes.tech AI
Odpověď od AI
Completer je třída v knihovně dart:async, která umožňuje vytvořit Future a dokončit jej později s nějakou hodnotou nebo chybou. Je užitečný, když asynchronní operace přímo nevrací Future, ale lze ji oznámit jejím dokončením.
import 'dart:async';
void main() async {
final completer = Completer<String>(); // Vytvoříme Completer pro Future<String>
// Simulace asynchronní operace
Future.delayed(Duration(seconds: 2), () {
// Dokončíme Future s úspěšnou hodnotou
completer.complete("Operace úspěšně dokončena!");
// completer.completeError(StateError("Něco se pokazilo!")); // nebo s chybou
});
print("Čekáme na dokončení operace...");
try {
// Získáme Future z Completer a počkáme na jeho dokončení
final result = await completer.future;
print("Výsledek: $result");
} catch (e) {
print("Došlo k chybě: $e");
}
}
V Flutteru se Completer často používá pro:
- Integraci s nativními API: Když nativní kód volá zpětné volání (callback) při dokončení operace, lze použít
Completerk převodu tohoto na Future v Dart. - Implementaci vlastních asynchronních operací: Pokud je potřeba vytvořit asynchronní funkci, která nepoužívá existující API vracející Future.
- Interakci mezi izoláty: Pro signalizaci dokončení práce v jiném izolátu.
Příklad použití v Flutteru s nativním API (hypotetický):
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');
// Předpokládá se, že nativní kód zavolá metodu 'operationCompleted'
// s výsledkem nebo chybou, a my posloucháme tyto volání.
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("Neznámý výsledek nativní operace"));
}
// Odstranit handler, pokud již není potřeba
platform.setMethodCallHandler(null);
}
return true; // Označujeme, že volání bylo zpracováno
});
} on PlatformException catch (e) {
completer.completeError(e);
}
return completer.future; // Vrací Future, které bude dokončeno později
}
}
// V widgetu nebo jinde:
// final service = NativeService();
// try {
// final nativeResult = await service.performNativeOperation();
// print("Nativní výsledek: $nativeResult");
// } catch (e) {
// print("Chyba nativní operace: $e");
// }