You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者无夜之星辰

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:03:20