Flutter中点击返回按钮时如何终止所有正在执行的异步任务
实现方案
你可以通过以下两种常用方案实现点击返回时终止getData函数的执行逻辑:
方案1:添加取消标记(最简实现)
这种方案通过标记位丢弃异步返回后的后续逻辑,实现成本极低:
- 首先在当前State类中新增取消标记:
// 定义在State类中 bool _isFetchCancelled = false;
- 修改返回按钮的点击逻辑,点击时先标记为取消再执行返回:
BackButton( onPress: () { _isFetchCancelled = true; Navigator.pop(context); }, svgAssetsPath: "assets/icons/icon_back.svg", height: SizeConfig.devicePixelRatio * 8, width: SizeConfig.devicePixelRatio * 8, ),
- 修改
getData函数,异步操作完成后先判断是否已取消,已取消就直接终止后续逻辑:
void getData(String locale, String searchKey, List<String> contentType, int categoryID, int start, int limit) async { print('get data'); temp = (await context.read(knowledgeBaseViewModelProvider).getCategoryData( locale, searchKey, contentType, categoryID, start, limit))!; _isLoding = false; // 新增判断:如果已经触发取消,直接终止后续执行 if (_isFetchCancelled) return; if(mounted){ setState(() { if (temp.length == 0 ) { isEnd = true; momAlertBox( context, "Alert", "No More Data.Try Another Category!", "Oky.", () => Navigator.pop(context, 'OK'), ); } else { isEnd = false; } isLodingState = false; items.addAll(temp); }); } }
注意:该方案仅丢弃异步返回后的后续逻辑,网络请求本身会正常跑完,适合对流量消耗不敏感的场景。
方案2:使用CancelableOperation彻底终止异步任务
如果需要连正在执行的网络请求也提前终止,可以用官方async包提供的可取消异步操作:
- 先引入async包(Flutter SDK默认自带对应版本,可直接导入):
import 'package:async/async.dart';
- 在State类中定义可取消操作实例:
CancelableOperation? _fetchOperation;
- 改造
getData函数,把异步请求封装进CancelableOperation:
void getData(String locale, String searchKey, List<String> contentType, int categoryID, int start, int limit) async { print('get data'); // 把异步请求封装为可取消操作 _fetchOperation = CancelableOperation.fromFuture( context.read(knowledgeBaseViewModelProvider).getCategoryData( locale, searchKey, contentType, categoryID, start, limit ) ); final result = await _fetchOperation?.value; // 如果任务已被取消,直接返回 if (_fetchOperation?.isCanceled ?? true) return; temp = result!; _isLoding = false; if(mounted){ setState(() { if (temp.length == 0 ) { isEnd = true; momAlertBox( context, "Alert", "No More Data.Try Another Category!", "Oky.", () => Navigator.pop(context, 'OK'), ); } else { isEnd = false; } isLodingState = false; items.addAll(temp); }); } }
- 修改返回按钮逻辑,点击时先取消异步任务再返回:
BackButton( onPress: () { _fetchOperation?.cancel(); Navigator.pop(context); }, svgAssetsPath: "assets/icons/icon_back.svg", height: SizeConfig.devicePixelRatio * 8, width: SizeConfig.devicePixelRatio * 8, ),
拓展:如果你的网络请求是基于Dio实现的,也可以直接使用Dio自带的
CancelToken,在返回时调用cancelToken.cancel()即可直接终止正在进行的网络请求,效果更好。
内容的提问来源于stack exchange,提问作者Shashiwadana
相关产品推荐
相关产品推荐

