Sobes.tech
Middle

O que é um Completer em Dart e como pode ser usado no desenvolvimento Flutter?

sobes.tech IA

Resposta da IA

Completer é uma classe na biblioteca dart:async que permite criar um Future e completá-lo mais tarde com um valor ou erro. É útil quando uma operação assíncrona não retorna um Future diretamente, mas pode ser notificada sobre sua conclusão.

import 'dart:async';

void main() async {
  final completer = Completer<String>(); // Criar um Completer para Future<String>

  // Simulação de uma operação assíncrona
  Future.delayed(Duration(seconds: 2), () {
    // Completar o Future com um valor bem-sucedido
    completer.complete("Operação concluída com sucesso!");
    // completer.completeError(StateError("Algo correu mal!")); // Ou com erro
  });

  print("Aguardando a operação terminar...");

  try {
    // Obter o Future do Completer e esperar sua conclusão
    final result = await completer.future;
    print("Resultado: $result");
  } catch (e) {
    print("Ocorreu um erro: $e");
  }
}

No Flutter, Completer é frequentemente usado para:

  • Integração com APIs nativas: Quando o código nativo chama um callback ao terminar uma operação, pode-se usar Completer para convertê-lo em um Future em Dart.
  • Implementação de operações assíncronas personalizadas: Se precisar criar uma função assíncrona que não utilize APIs existentes que retornem Future.
  • Interação entre isolados: Para sinalizar a conclusão de trabalho em outro isolado.

Exemplo de uso em Flutter com API nativa (hipotético):

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

      // Presume-se que o código nativo chamará o método 'operationCompleted'
      // com o resultado ou erro, e escutamos essas chamadas.
      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("Resultado nativo desconhecido"));
          }
          // Remover o handler se não for mais necessário
          platform.setMethodCallHandler(null);
        }
        return true; // Indica que a chamada foi tratada
      });

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

    return completer.future; // Retorna o Future que será concluído mais tarde
  }
}

// No widget ou outro lugar:
// final service = NativeService();
// try {
//   final nativeResult = await service.performNativeOperation();
//   print("Resultado nativo: $nativeResult");
// } catch (e) {
//   print("Erro na operação nativa: $e");
// }