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 често се използва за:

  • Интеграция с нативни API: Когато нативният код извиква обратен повик (callback) при завършване на операцията, може да се използва Completer за преобразуването му в Future в Dart.
  • Реализация на персонализирани асинхронни операции: Ако трябва да създадете асинхронна функция, която не използва съществуващи API, връщащи Future.
  • Взаимодействие между изолати: За сигнализиране за завършване на работа в друг изолат.

Пример за използване във Flutter с нативен 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');

      // Предполага се, че нативният код ще извика метода '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("Неизвестен резултат от нативната операция"));
          }
          // Премахване на обработчика, ако вече не е нужен
          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("Нативен резултат: $nativeResult");
// } catch (e) {
//   print("Грешка при нативната операция: $e");
// }