Future Completer em Dart

Tempo de leitura: 3 minutes

Este blog irá explorar a linguagem de programação Future Completer em Dart. Veremos como executar um programa de demonstração. Aprenda como implementá-lo e usá-lo em seus aplicativos. O que também funciona para a estrutura Flutter.

 

Introdução

Se você estiver utilizando o Dart ou desenvolvendo um aplicativo Flutter, você já deve conhecer o Future. Future é normalmente usado para lidar com tarefas assíncronas. Obter a consequência de um Futuro é muito simples.

Por exemplo, se tivermos uma capacidade Future fetchResult(), é possível obter o resultado utilizando a palavra-chave await.

String result = await fetchResult();

Outra alternativa é usar uma cadeia Future.

fetchResult()
   .then((value) {
     print(value);
   });

No entanto, em alguns casos, é impossível usar os métodos acima para criar um Future. Por exemplo, se você precisar obter o resultado Future de uma função de retorno de chamada. Vamos dar uma olhada no exemplo abaixo. Existe uma classe MyExectuor que possui um método run. O construtor da classe possui um retorno de chamada onDone obrigatório. O método run chamará o método onDone com um valor. O objetivo aqui é fazer com que o valor seja passado para o retorno de chamada onDone.

import 'dart:async';
  
  class MyExecutor {
  
    void Function(String time) onDone;
  
    MyExecutor({
      required this.onDone,
    });
  
    Future<void> run() async {
      await Future.delayed(Duration(seconds: 2));
      final DateTime time = DateTime.now();
      final String formattedTime = '${time.year}-${time.month}-${time.day} ${time.hour}:${time.minute}:${time.second}';
      onDone(formattedTime);
    }
  }
  
  main() async {
    final MyExecutor myExecutor = MyExecutor(
      onDone: (String time) async {
        // queremos obter o valor quando este retorno de chamada for invocado
      }
    );
 
    await myExecutor.run();
 
  }

Como o método run retorna void, e isso significa que não retorna nada, não podemos esclarecer o valor usando await.run(). Se todas as coisas forem iguais, precisamos obter o valor do retorno de chamada passado.

Completer:

Em primeiro lugar, você deseja criar um Completer chamando seu construtor. Possui um parâmetro de tipo onde você pode caracterizar o tipo de retorno. A seguir está uma ilustração de um Completer que lucra com uma string.

final stringCompleter = Completer<String>();

Caso não tenha um valor de retorno, você pode criar um Completer com um tipo de parâmetro void.

final voidCompleter = Completer<>();

Caso você não determine o parâmetro de tipo, ele será definido como dynamic.

final dynamicCompleter = Completer(); // Completer<dynamic>

 

Complete Future:

Para finalizar o Future, você pode chamar a técnica complete com um valor de retorno. O tipo de valor deve ser equivalente ao parâmetro de tipo ao fazer o Completer. Supondo que o limite de classificação seja nulo, você não precisa passar nenhum valor. Na eventualidade de ser dinâmico, você pode retornar um valor de qualquer tipo. Possivelmente, você tem permissão para retornar nulo, assumindo que o parâmetro de classificação é nulo ou anulável.

void complete([FutureOr<T>? value]);

A seguir está uma ilustração de como finalizar o Future com um valor de string.

stringCompleter.complete('foo');

A técnica complete deve ser chamada uma vez. Se o que está reservado a partir de agora for complete e você chamar o método complete mais uma vez, ele lançará StateError.

 

Complete Futuro com Error

Um Futuro também pode lançar um erro. Com o Completer, gerar um erro deve ser possível chamando a técnica completeError.

void completeError(Object error, [StackTrace? stackTrace]);

Aqui está uma ilustração de como chamar a técnica completeError

try {
  // Faça alguma coisa
} catch (ex, stackTrace) {
  stringCompleter.completeError(ex, stackTrace);
}

 

Get Future e Value:

Supondo que você tenha um caso Completer, você pode acessar a propriedade future para obter o Future que será finalizado quando complete ou completeError for chamado. Supondo que você tenha o Future, você pode utilizar a palavra-chave wait para retornar o valor do Future.

final valueFuture = stringCompleter.future;
final value = await valueFuture;

Get Completion Status:

Para obter o status de conclusão Representando coisas para Future, você pode acessar a propriedade isCompleted.

final isCompleted = stringCompleter.isCompleted;

Vamos juntar todo o código:

import 'dart:async';

class MyExecutor {
  void Function(String time) onDone;

  MyExecutor({
    required this.onDone,
  });

  Future<void> run() async {
    await Future.delayed(Duration(seconds: 2));
    final DateTime time = DateTime.now();
    final String formattedTime =
        '${time.year}-${time.month}-${time.day} ${time.hour}:${time.minute}:${time.second}';
    onDone(formattedTime);
  }
}

main() async {
  final stringCompleter = Completer<String>();

  final MyExecutor myExecutor = MyExecutor(onDone: (String time) async {
    try {
      if (time.isNotEmpty) {
        stringCompleter.complete(time);
      } else {
        throw Exception('empty time');
      }
    } catch (ex, stackTrace) {
      stringCompleter.completeError(ex, stackTrace);
    }
  });

  print('isCompleted: ${stringCompleter.isCompleted}');

  await myExecutor.run();

  print('isCompleted: ${stringCompleter.isCompleted}');
  final valueFuture = stringCompleter.future;
  final value = await valueFuture;
  print('value: $value');
}

Quando executamos o aplicativo, devemos obter a saída da tela como a saída do console abaixo da tela.

isCompleted: false
isCompleted: true
value: 2023-11-15 12:25:11

Process finished with exit code 0

 

Conclusão

No artigo, expliquei o Future Completer In Dart; você pode modificar este código de acordo com sua escolha. Esta foi uma pequena introdução ao Future Completer em Dart Interação com o usuário da minha parte, e está funcionando usando Flutter.

Completer pode ser utilizado como uma opção para fazer um Future em Dart/Flutter. A utilização é muito básica. Se você quiser fazer um Completer, chame a estratégia complete ou completeError. Você pode obter o Futuro de um Completador na propriedade futura. A propriedade isCompleted pode ser utilizada para saber se o que está no futuro foi concluído.

Espero que este blog forneça informações suficientes sobre como experimentar o Future Completer In Dart de seus projetos. Então, por favor, experimente.