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

如何在FutureBuilder的Future.wait中缓存Future避免状态变化时重复构建

解决方案

问题根源

你当前将Future.wait([...])直接写在FutureBuilder的future参数中,每次组件重建都会生成新的Future实例,即使内部的单个Future已经执行完毕,FutureBuilder检测到future参数变化也会重新触发等待逻辑,导致重复执行请求。

实现缓存的方案

你使用了GetX的控制器,直接将组合后的Future缓存到控制器中即可,控制器的生命周期独立于页面build,不会因为页面状态变化被销毁,适合做缓存载体。

步骤1:修改控制器代码,提前缓存组合Future

在OrdersMainController中声明组合Future变量,在初始化钩子onInit中一次性组装好,后续复用该实例即可:

class OrdersMainController extends GetxController {
  // 你原有声明的单个请求Future
  late Rx<Future> ordersFuture;
  // 新增:缓存组合后的多Future实例
  late Future<List<dynamic>> combinedFutures;

  @override
  void onInit() {
    super.onInit();
    // 你原有给ordersFuture赋值的逻辑保持不变
    ordersFuture = Rx(请求订单的方法());
    // 初始化时一次性组装好组合Future,不要每次build都重新生成
    combinedFutures = Future.wait([ordersFuture.value]);
  }

  // 可选:如果需要下拉刷新等重新请求的场景,加个刷新方法更新缓存即可
  void refreshOrderData() {
    // 重新生成请求Future
    ordersFuture.value = 请求订单的方法();
    // 更新组合Future缓存
    combinedFutures = Future.wait([ordersFuture.value]);
    // 触发GetBuilder重建
    update();
  }
}

步骤2:修改FutureBuilder的future参数

直接引用控制器中缓存好的组合Future,不要在build方法内当场生成Future.wait实例:

GetBuilder<OrdersMainController>(builder: (controller) {
  return FutureBuilder(
    // 直接用已缓存的组合Future,不要写Future.wait([controller.ordersFuture.value])
    future: controller.combinedFutures,
    builder: (context, snapshot) {
      // 你原有builder逻辑保持不变即可
      switch (snapshot.connectionState) {
        case ConnectionState.active:
        case ConnectionState.waiting:
          return const Center(child: CircularProgressIndicator());
        case ConnectionState.done:
          if (snapshot.hasError) {
            return SizedBox(
                width: double.infinity,
                height: 600,
                child: Center(
                    child: Text(snapshot.error.toString(),
                        style: Theme.of(context).textTheme.caption!)));
          }
          controller.ordersData.value = (snapshot.data! as List)[0];
          final DataTableSource _data = OrdersMainSource(controller.ordersData.value.data!);
          return ...; // 你的页面布局逻辑
        default:
          return const SizedBox();
      }
    });
})

注意事项

  • 如果你有多个不同的Future需要组合,只需要在combinedFutures的Future.wait数组中加入对应的缓存Future即可,已经执行完成的Future被复用的时候,不会重复发起请求,会直接返回之前的执行结果。
  • 所有需要复用的Future实例都不要在build方法中生成,统一放到控制器或者State的生命周期方法中初始化,可以从根源避免重复执行的问题。

内容的提问来源于stack exchange,提问作者Umut Arpat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:30:02