4
votes

Dart: délai de publication annulable / futur

Je suis nouveau dans le flutter et je souhaite traduire du texte à partir d'un InputField en appelant une API. Cependant, je ne veux pas l'appeler à chaque coup de touche, mais uniquement lorsque l'utilisateur a interrompu la saisie.

Sur Android, j'utiliserais simplement la classe Handler avec postDelay () en appelant au préalable removeAllCallbacksAndMessages (null) . Existe-t-il un moyen de faire quelque chose de similaire sur Dart?

Voici mon code actuel:

@override
  Stream<State> mapEventToState(Event event) async* {
    if (event is QueryChangeEvent) {
      yield TextTranslationChangeState(
          query: event.query ?? "",
          translation: await _repo.getTranslation(event.query, currentState.fromLang, currentState.toLang));
  }

Modifier 1 p>

J'appelle le code de mon Bloc comme ceci:

Future<String> getTranslation(String query, Language from, Language to) async {
    // cancel here if a call to this function was less than 500 millis ago.
    return Future.delayed(const Duration(milliseconds: 500), () {
      return _translator.translate(query, from: from.code, to: to.code)
    });
  }

C'est pourquoi je ne peux pas appeler .then () sur l'avenir car je ne pourrais pas obtenir le nouvel état du bloc de la fonction imbriquée.

Toute aide est appréciée!


3 Réponses :


0
votes

En supposant que vous utilisez un TextField pour votre saisie, vous pouvez appeler getTranslation () sur le onSubmitted , qui sera appelé lorsque l'utilisateur aura fini de modifier:

 TextField(
   onSubmitted: (value) {
     getTranslation(value, 'en', 'ru'); 
   },
 );


1 commentaires

Merci mais je dois l'appeler lorsque l'utilisateur a interrompu la saisie, pas lorsqu'il a explicitement soumis sa requête. Le délai est juste pour éviter d'appeler l'API pour chaque caractère et pour éviter les conditions de concurrence.



2
votes

0 commentaires

3
votes

Vous pouvez annuler l'opération asynchrone Future en utilisant CancelableOperation .

Voici un exemple (ps j'ai simplifié la signature de votre méthode pour que je puisse la tester facilement)

I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Operation Cancelled
I/flutter ( 7312): Then called: Hello

Sur l'écouteur de texte modifié:

  onTextChanged() {
    fromCancelable(getTranslation("query", "EN", "TR")).then((value) {
      print("Then called: $value");
    });
  }

Exemple de sortie:

  CancelableOperation cancellableOperation;

  Future<dynamic> fromCancelable(Future<dynamic> future) async {
    cancellableOperation?.cancel();
    cancellableOperation = CancelableOperation.fromFuture(future, onCancel: () {
      print('Operation Cancelled');
    });
    return cancellableOperation.value;
  }

  Future<dynamic> getTranslation(String query, String from, String to) async {
    return Future.delayed(const Duration(milliseconds: 1000), () {
      return "Hello";
    });
  }


0 commentaires