Sobes.tech
Middle

Wat is een Completer in Dart en hoe kan het worden gebruikt in Flutter-ontwikkeling?

sobes.tech AI

Antwoord van AI

Completer is een klasse in de bibliotheek dart:async die het mogelijk maakt om een Future te creëren en deze later te voltooien met een waarde of fout. Het is handig wanneer een asynchrone operatie niet direct een Future retourneert, maar er wel over kan worden geïnformeerd dat deze is voltooid.

import 'dart:async';

void main() async {
  final completer = Completer<String>(); // Maak een Completer voor Future<String>

  // Simulatie van een asynchrone operatie
  Future.delayed(Duration(seconds: 2), () {
    // Voltooi de Future met een succesvolle waarde
    completer.complete("Operatie succesvol voltooid!");
    // completer.completeError(StateError("Er ging iets mis!")); // Of met een fout
  });

  print("Wachten op voltooiing van de operatie...");

  try {
    // Haal de Future op uit de Completer en wacht tot deze is voltooid
    final result = await completer.future;
    print("Resultaat: $result");
  } catch (e) {
    print("Er trad een fout op: $e");
  }
}

In Flutter wordt Completer vaak gebruikt voor:

  • Integratie met native API's: Wanneer native code een callback aanroept bij het voltooien van een operatie, kan Completer worden gebruikt om dit om te zetten in een Future in Dart.
  • Implementatie van aangepaste asynchrone operaties: Als je een asynchrone functie wilt maken die geen bestaande Future-API's gebruikt.
  • Interactie tussen isolates: Om het voltooien van werk in een andere isolate te signaleren.

Voorbeeld van gebruik in Flutter met een hypothetische native API:

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');

      // Er wordt aangenomen dat native code de methode 'operationCompleted' aanroept
      // met het resultaat of een fout, en we luisteren naar deze calls.
      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("Onbekend native resultaat"));
          }
          // Handler verwijderen als niet meer nodig
          platform.setMethodCallHandler(null);
        }
        return true; // Geeft aan dat de call is afgehandeld
      });

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

    return completer.future; // Geeft een Future terug dat later wordt voltooid
  }
}

// In een widget of andere plek:
// final service = NativeService();
// try {
//   final nativeResult = await service.performNativeOperation();
//   print("Native resultaat: $nativeResult");
// } catch (e) {
//   print("Fout bij native operatie: $e");
// }