Sobes.tech
Middle

Šta je Completer u Dart-u i kako ga možete koristiti u razvoju Flutter-a?

sobes.tech АИ

Одговор од АИ

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");
// }