Ответ
Непосредственно отменить стандартный Future нельзя, так как он представляет собой уже запущенную асинхронную операцию. Однако можно реализовать логику отмены с помощью нескольких подходов.
1. Использование Completer для ручного управления:
Future<String> cancellableOperation(Duration delay) {
final completer = Completer<String>();
final timer = Timer(delay, () {
if (!completer.isCompleted) {
completer.complete('Operation completed');
}
});
// Возвращаем future, который можно "отменить", завершив completer досрочно
return completer.future.whenComplete(() => timer.cancel());
}
// Использование
final future = cancellableOperation(Duration(seconds: 5));
// Для "отмены" нужно где-то сохранить completer и вызвать completer.completeError('Cancelled')
2. Пакет async с CancelableOperation (рекомендуется):
import 'package:async/async.dart';
Future<void> main() async {
final operation = CancelableOperation.fromFuture(
Future.delayed(Duration(seconds: 5), () => 'Result'),
onCancel: () => Future.value('Cancelled'),
);
// Отмена через 2 секунды
Future.delayed(Duration(seconds: 2), () {
operation.cancel();
print('Operation cancelled');
});
try {
final result = await operation.value;
print(result);
} catch (e) {
print('Error: $e'); // CanceledException при отмене
}
}
3. Для сетевых запросов используйте специализированные механизмы:
- В dio:
CancelToken - В http: закрытие клиента или использование
Streamс таймаутами
Важно: Отмена Future не прерывает уже выполняющийся код (например, CPU-интенсивные вычисления), а только предотвращает обработку результата. Для реальной отмены длительных операций нужно периодически проверять флаг отмены.