is there any way to cancel a dart Future? is there any way to cancel a dart Future? dart dart

is there any way to cancel a dart Future?


You can use CancelableOperation or CancelableCompleter to cancel a future. See below the 2 versions:

Solution 1: CancelableOperation (included in a test so you can try it yourself):

  • cancel a future

test("CancelableOperation with future", () async {  var cancellableOperation = CancelableOperation.fromFuture(    Future.value('future result'),    onCancel: () => {debugPrint('onCancel')},  );// cancellableOperation.cancel();  // uncomment this to test cancellation  cancellableOperation.value.then((value) => {    debugPrint('then: $value'),  });  cancellableOperation.value.whenComplete(() => {    debugPrint('onDone'),  });});
  • cancel a stream

test("CancelableOperation with stream", () async {  var cancellableOperation = CancelableOperation.fromFuture(    Future.value('future result'),    onCancel: () => {debugPrint('onCancel')},  );  //  cancellableOperation.cancel();  // uncomment this to test cancellation  cancellableOperation.asStream().listen(        (value) => { debugPrint('value: $value') },    onDone: () => { debugPrint('onDone') },  );});

Both above tests will output:

then: future resultonDone

Now if we uncomment the cancellableOperation.cancel(); then both above tests will output:

onCancel

Solution 2: CancelableCompleter (if you need more control)

test("CancelableCompleter is cancelled", () async {  CancelableCompleter completer = CancelableCompleter(onCancel: () {    print('onCancel');  });  // completer.operation.cancel();  // uncomment this to test cancellation  completer.complete(Future.value('future result'));  print('isCanceled: ${completer.isCanceled}');  print('isCompleted: ${completer.isCompleted}');  completer.operation.value.then((value) => {    print('then: $value'),  });  completer.operation.value.whenComplete(() => {    print('onDone'),  });});

Output:

isCanceled: falseisCompleted: truethen: future resultonDone

Now if we uncomment the cancellableOperation.cancel(); we get output:

onCancelisCanceled: trueisCompleted: true

Be aware that if you use await cancellableOperation.value or await completer.operation then the future will never return a result and it will await indefinitely if the operation was cancelled. This is because await cancellableOperation.value is the same as writing cancellableOperation.value.then(...) but then() will never be called if the operation was cancelled.

Remember to add async Dart package.

Code gist


How to cancel Future.delayed

A simple way is to use Timer instead :)

Timer _timer;void _schedule() {  _timer = Timer(Duration(seconds: 2), () {     print('Do something after delay');  });}@overridevoid dispose() {  super.dispose();  _timer?.cancel();}


As far as I know, there isn't a way to cancel a Future. But there is a way to cancel a Stream subscription, and maybe that can help you.

Calling onSubmit on a button returns a StreamSubscription object. You can explicitly store that object and then call cancel() on it to cancel the stream subscription:

StreamSubscription subscription = someDOMElement.onSubmit.listen((data) {   // you code here   if (someCondition == true) {     subscription.cancel();   }});

Later, as a response to some user action, perhaps, you can cancel the subscription: