Как отменить выполнение асинхронной операции в Flutter?

 В Flutter для отмены асинхронных операций можно использовать Future или Stream, а также механизм отмены, предоставляемый через объекты Cancelable или CancelableOperation из пакета async. В зависимости от того, какой вид асинхронной операции используется, подход будет отличаться.

Вот несколько способов, как отменить асинхронную операцию:

1. Использование CancelableOperation (из пакета async)

CancelableOperation позволяет отменять операцию до того, как она завершится.

Пример:

import 'package:async/async.dart';

void main() async {
  // Создаем отменяемую операцию
  CancelableOperation<void> operation = CancelableOperation.fromFuture(
    Future.delayed(Duration(seconds: 5), () {
      print('Операция завершена');
    }),
  );

  // Отмена операции через 2 секунды
  Future.delayed(Duration(seconds: 2), () {
    operation.cancel();
    print('Операция отменена');
  });

  // Ждем завершения операции или ее отмены
  await operation.valueOrCancellation();
}

Здесь операция будет отменена через 2 секунды, до того как она успеет выполниться.

2. Использование токенов отмены с помощью StreamSubscription

Если вы используете Stream, можно отменить подписку на поток через метод .cancel().

Пример:

void main() async {
  Stream<int> stream = Stream.periodic(Duration(seconds: 1), (x) => x);
  StreamSubscription<int> subscription = stream.listen((value) {
    print(value);
  });

  // Отменить через 3 секунды
  Future.delayed(Duration(seconds: 3), () {
    subscription.cancel();
    print('Подписка отменена');
  });
}

3. Использование флага для отмены асинхронной операции

Если у вас есть долгоживущая операция, можно использовать флаг для ручной отмены.

Пример:

bool isCancelled = false;

Future<void> longOperation() async {
  for (int i = 0; i < 10; i++) {
    if (isCancelled) {
      print('Операция отменена');
      return;
    }
    await Future.delayed(Duration(seconds: 1));
    print('Операция продолжается: шаг $i');
  }
  print('Операция завершена');
}

void main() async {
  longOperation();

  // Отмена через 3 секунды
  Future.delayed(Duration(seconds: 3), () {
    isCancelled = true;
  });
}

Этот метод особенно полезен, если вы хотите отменить операцию вручную, например, при работе с циклами или длительными задачами.

Итоги:

  • Для простых операций удобно использовать CancelableOperation.
  • Для потоков данных — метод .cancel() на StreamSubscription.
  • Для других сценариев можно использовать флаги и логику отмены в асинхронных задачах вручную.