Future.wait首次执行后不再触发子任务的原因及解决方案
Dart Future复用问题分析与修复
现象原因
Dart里的Future是一次性状态对象,一旦完成(进入completed状态),后续再对它进行监听或用Future.wait等待,只会直接返回已有的完成结果,不会重新触发对应的异步任务。
你的代码中,从Page1跳转到Page2时,[_load1(), _load2()]会立刻执行这两个方法,生成两个已经启动的Future实例并传给Page2。首次点击按钮时,这两个Future可能还未执行完毕,所以能输出load1 finish、load2 finish;但后续点击时,这两个Future早已处于完成状态,Future.wait会直接触发then回调,只会输出all finish。
修复方案
不要直接传递已生成的Future实例,改成传递能生成Future的函数,这样每次点击按钮时,都调用这些函数生成新的Future,重新执行异步任务。
修改后的完整代码:
class _Page1 extends StatelessWidget { const _Page1({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('page 1'), ), body: ElevatedButton( child: const Text('push page 2'), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => _Page2( // 传递函数本身,不执行 requestFactories: [_load1, _load2], ), ), ); }, ), ); } Future<void> _load1() { return Future.delayed(const Duration(seconds: 1), () { log('load1 finish'); }); } Future<void> _load2() { return Future.delayed(const Duration(seconds: 2), () { log('load2 finish'); }); } } class _Page2 extends StatelessWidget { const _Page2({Key? key, required this.requestFactories}) : super(key: key); // 定义为生成Future的函数列表 final List<Future Function()> requestFactories; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('page 2'), ), body: ElevatedButton( child: const Text('future wait'), onPressed: () { // 每次点击都生成新的Future实例 final requests = requestFactories.map((factory) => factory()).toList(); Future.wait(requests).then((value) { log('all finish'); }); }, ), ); } }
这样每次点击Page2的按钮,都会重新调用_load1和_load2生成新的Future,异步任务会重新执行,每次都能输出完整的日志。
内容的提问来源于stack exchange,提问作者无夜之星辰
相关产品推荐
相关产品推荐

