Sobes.tech
Middle

Čo je to Completer v Dart a ako ho môžete použiť pri vývoji Flutter?

sobes.tech AI

Odpoveď od AI

Completer je trieda v knižnici dart:async, ktorá umožňuje vytvoriť Future a dokončiť ho neskôr s nejakou hodnotou alebo chybou. Je užitočný, keď asynchrónna operácia priamo nevracia Future, ale môže byť oznámená o jej ukončení.

import 'dart:async';

void main() async {
  final completer = Completer<String>(); // Vytvoríme Completer pre Future<String>

  // Simulácia asynchrónnej operácie
  Future.delayed(Duration(seconds: 2), () {
    // Ukončíme Future s úspešnou hodnotou
    completer.complete("Operácia úspešne dokončená!");
    // completer.completeError(StateError("Niečo sa pokazilo!")); // alebo s chybou
  });

  print("Čakáme na dokončenie operácie...");

  try {
    // Získame Future z Completer a počkáme na jeho dokončenie
    final result = await completer.future;
    print("Výsledok: $result");
  } catch (e) {
    print("Vyskytla sa chyba: $e");
  }
}

V Flutteri sa Completer často používa na:

  • Integráciu s natívnymi API: Keď natívny kód volá spätné volanie (callback) pri ukončení operácie, možno použiť Completer na jeho prevedenie na Future v Dart.
  • Implementáciu vlastných asynchrónnych operácií: Ak je potrebné vytvoriť asynchrónnu funkciu, ktorá nevyužíva existujúce API vracajúce Future.
  • Interakciu medzi izolátmi: Na signalizáciu ukončenia práce v inom izoláte.

Príklad použitia v Flutteri s natívnym 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');

      // Predpokladá sa, že natívny kód zavolá metódu 'operationCompleted'
      // s výsledkom alebo chybou, a my sledujeme tieto volania.
      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ámy výsledok nativnej operácie"));
          }
          // Odstrániť handler, ak už nie je potrebný
          platform.setMethodCallHandler(null);
        }
        return true; // Označujeme, že volanie bolo spracované
      });

    } on PlatformException catch (e) {
      completer.completeError(e);
    }

    return completer.future; // Vrátime Future, ktoré bude dokončené neskôr
  }
}
// V widgete alebo inom mieste:
// final service = NativeService();
// try {
//   final nativeResult = await service.performNativeOperation();
//   print("Nativný výsledok: $nativeResult");
// } catch (e) {
//   print("Chyba nativnej operácie: $e");
// }