CancelableOperation调用cancel后_trytest()仍执行完毕的问题
解决CancelableOperation无法取消_trytest()方法的问题
问题现象
用async: ^2.9.0库的CancelableOperation想取消_trytest()方法,但点击Cancel按钮后,_trytest()还是会完整执行,控制台输出:
flutter: on _trytest flutter: onCancel flutter: Completed
相关代码如下:
变量声明
CancelableOperation<void> cancellableOperation = CancelableOperation.fromFuture( Future.value('future result'), onCancel: () {}, );
UI部分代码
_isloading ? Column( children: [ Center( child: CircularProgressIndicator(), ), ElevatedButton( child: Text('Cancel'), onPressed: () { cancellableOperation.cancel(); }, ), ], ) : ElevatedButton( child: Text('Delete Account'), onPressed: () { setState(() { _isloading = true; }); cancellableOperation = CancelableOperation.fromFuture( _trytest(), onCancel: () => { debugPrint('onCancel'), cancellableOperation.cancel(), setState(() { _isloading = false; }) }); }, ),
_trytest()方法
Future<void> _trytest() async { print('on _trytest'); await Future.delayed(Duration(seconds: 4)).then((value) => { print("Completed"), setState(() { _isloading = false; }) }); }
问题原因
CancelableOperation.fromFuture()只是包装现有Future,但没法中断已经启动的异步任务。_trytest()里的Future.delayed一旦开始执行就会跑完,Cancel操作只会触发onCancel回调,不会终止内部的异步逻辑。
解决方案
要真正取消任务,得在_trytest()内部监听取消状态,主动终止后续执行。以下是两种可行的修改方式:
方式一:在_trytest()内部检查取消状态
- 修改
_trytest()方法,接收CancelableOperation参数并判断取消状态:
Future<void> _trytest(CancelableOperation<void> operation) async { print('on _trytest'); await Future.delayed(Duration(seconds: 4)).then((value) { // 先判断是否取消,再执行后续逻辑 if (!operation.isCanceled) { print("Completed"); setState(() { _isloading = false; }); } }); }
- 更新UI中创建
CancelableOperation的代码,把当前实例传入_trytest():
cancellableOperation = CancelableOperation.fromFuture( _trytest(cancellableOperation), onCancel: () { debugPrint('onCancel'); setState(() { _isloading = false; }); }, );
方式二:用CancelableOperation的then回调处理完成逻辑
- 简化
_trytest()方法:
Future<void> _trytest() async { print('on _trytest'); await Future.delayed(Duration(seconds: 4)); }
- 修改UI的点击事件,在
CancelableOperation的then回调中判断取消状态:
onPressed: () { setState(() { _isloading = true; }); cancellableOperation = CancelableOperation.fromFuture( _trytest(), onCancel: () { debugPrint('onCancel'); setState(() { _isloading = false; }); }, ); // 仅当未取消时执行完成逻辑 cancellableOperation.then((_) { if (!cancellableOperation.isCanceled) { print("Completed"); setState(() { _isloading = false; }); } }); }
关键说明
CancelableOperation的作用是管理取消回调、阻止后续then/whenComplete等回调执行,但没法直接中断已启动的异步操作。- 必须在异步任务的关键节点主动检查取消状态,放弃后续逻辑,才能实现真正的“取消”效果。
内容的提问来源于stack exchange,提问作者ismail
相关产品推荐
相关产品推荐

