Sobes.tech
Middle

Τι είναι ένα Completer στη Dart και πώς μπορεί να χρησιμοποιηθεί στην ανάπτυξη Flutter;

sobes.tech AI

Απάντηση από AI

Το Completer είναι μια κλάση στη βιβλιοθήκη dart:async που επιτρέπει τη δημιουργία ενός Future και την ολοκλήρωσή του αργότερα με μια τιμή ή σφάλμα. Είναι χρήσιμο όταν μια ασύγχρονη λειτουργία δεν επιστρέφει άμεσα ένα Future, αλλά μπορεί να ενημερωθεί για την ολοκλήρωσή της.

import 'dart:async';

void main() async {
  final completer = Completer<String>(); // Δημιουργία ενός Completer για Future<String>

  // Προσομοίωση μιας ασύγχρονης λειτουργίας
  Future.delayed(Duration(seconds: 2), () {
    // Ολοκλήρωση του Future με μια επιτυχής τιμή
    completer.complete("Η λειτουργία ολοκληρώθηκε με επιτυχία!");
    // completer.completeError(StateError("Κάτι πήγε στραβά!")); // Ή με σφάλμα
  });

  print("Αναμονή για την ολοκλήρωση της λειτουργίας...");

  try {
    // Λαμβάνουμε το Future από τον Completer και περιμένουμε να ολοκληρωθεί
    final result = await completer.future;
    print("Αποτέλεσμα: $result");
  } catch (e) {
    print("Παρουσιάστηκε σφάλμα: $e");
  }
}

Στο Flutter, το Completer χρησιμοποιείται συχνά για:

  • Ενσωμάτωση με native API: Όταν ο native κώδικας καλεί ένα callback στο τέλος μιας λειτουργίας, μπορούμε να χρησιμοποιήσουμε το Completer για να το μετατρέψουμε σε Future στο Dart.
  • Υλοποίηση προσαρμοσμένων ασύγχρονων λειτουργιών: Αν θέλετε να δημιουργήσετε μια ασύγχρονη συνάρτηση που δεν χρησιμοποιεί υπάρχουσες API που επιστρέφουν Future.
  • Αλληλεπίδραση μεταξύ isolates: Για να σηματοδοτήσετε την ολοκλήρωση εργασίας σε άλλο isolate.

Παράδειγμα χρήσης σε Flutter με μια υποθετική 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');

      // Υποτίθεται ότι ο native κώδικας θα καλέσει τη μέθοδο 'operationCompleted'
      // με το αποτέλεσμα ή το σφάλμα, και εμείς ακούμε αυτές τις κλήσεις.
      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("Άγνωστο native αποτέλεσμα"));
          }
          // Αφαίρεση του handler αν δεν χρειάζεται πλέον
          platform.setMethodCallHandler(null);
        }
        return true; // Δείχνει ότι η κλήση έχει διαχειριστεί
      });

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

    return completer.future; // Επιστρέφει το Future που θα ολοκληρωθεί αργότερα
  }
}

// Στο widget ή σε άλλο μέρος:
// final service = NativeService();
// try {
//   final nativeResult = await service.performNativeOperation();
//   print("Αποτέλεσμα native: $nativeResult");
// } catch (e) {
//   print("Σφάλμα native λειτουργίας: $e");
// }