Я новичок в флаттере и хочу перевести некоторый текст из InputField
, вызвав API. Однако я не хочу вызывать его при каждом нажатии клавиши, а только тогда, когда пользователь приостановил ввод.
На Android я бы просто использовал класс Handler
с postDelay()
с предварительным вызовом removeAllCallbacksAndMessages(null)
. Есть ли способ сделать что-то подобное на Dart?
Вот мой текущий код:
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)
});
}
Изменить 1
Я вызываю код из своего блока так:
@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));
}
Вот почему я не могу вызывать .then()
в будущем, потому что я не смогу получить новое состояние из блока вложенной функции.
Любая помощь приветствуется!
Предполагая, что вы используете TextField
для ввода, вы можете вызвать getTranslation()
на onSubmitted
, который будет вызван, когда пользователь закончит редактирование:
TextField(
onSubmitted: (value) {
getTranslation(value, 'en', 'ru');
},
);
Спасибо, но мне нужно вызвать его, когда пользователь приостановил ввод, а не когда он явно отправил свой запрос. Задержка предназначена только для предотвращения вызова API для каждого отдельного символа и предотвращения условий гонки.
Да есть, он называется Таймер
https://api.dartlang.org/stable/2.3.1/dart-async/Timer-class.html
Вы можете отложить выполнение, а также отменить триггер.
Вы можете добиться отмены асинхронной операции Future
, используя CancelableOperation
.
Вот пример (ps я упростил сигнатуру вашего метода, чтобы мне было легко его протестировать)
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";
});
}
При прослушивании измененного текста:
onTextChanged() {
fromCancelable(getTranslation("query", "EN", "TR")).then((value) {
print("Then called: $value");
});
}
Пример вывода:
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
Возможный дубликат есть ли способ отменить дротик Future?