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

如何让Flutter的Future与FutureBuilder持续更新展示的数据?

问题原因与解决方案

你的问题根源有两点:一是FutureBuilder会缓存传入的Future实例,只要这个实例不变,就不会重新执行异步请求;二是HTTP请求可能被系统或服务器缓存,导致返回旧数据。热重启后Future实例会重新创建,因此能获取到最新值。

解决步骤

1. 用State变量管理Future实例

不要直接在FutureBuilder的future参数中调用param(),而是在State类中保存Future对象,通过setState更新实例来触发重新请求:

class _YourWidgetState extends State<YourWidget> {
  late Future<String?> _fetchFuture;

  @override
  void initState() {
    super.initState();
    _fetchFuture = param(); // 初始化时发起第一次请求
  }

  // 手动触发刷新的方法
  void _refreshData() {
    setState(() {
      _fetchFuture = param(); // 创建新的Future实例,触发重新请求
    });
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String?>(
      future: _fetchFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasData) {
            var co2 = int.parse(snapshot.data!);
            return Column(
              children: [
                Text('$co2'),
                ElevatedButton(
                  onPressed: _refreshData,
                  child: Text('刷新数据'),
                ),
              ],
            );
          } else {
            return Text('无数据');
          }
        } else {
          return Text('wait');
        }
      },
    );
  }
}

2. 禁用HTTP请求缓存

修改param()函数,添加请求头禁止缓存,确保每次都从服务器拉取最新数据:

Future<String?> param() async {
  String url1 = "https://api.thingspeak.com/channels/1864145/fields/1/last.json";
  var response1 = await http.get(
    Uri.parse(url1),
    headers: {
      'Cache-Control': 'no-cache, no-store, must-revalidate',
      'Pragma': 'no-cache',
      'Expires': '0',
    },
  );

  field_1 fieldno1 = field_1.fromJson(jsonDecode(response1.body));
  String? co2 = fieldno1.field1;
  print(co2);
  return co2;
}

3. 定时自动刷新(可选)

如果需要自动更新数据,可以在initState中添加定时器,定期触发刷新:

Timer? _refreshTimer;

@override
void initState() {
  super.initState();
  _fetchFuture = param();
  // 每5秒自动刷新一次
  _refreshTimer = Timer.periodic(Duration(seconds: 5), (timer) {
    _refreshData();
  });
}

@override
void dispose() {
  // 页面销毁时取消定时器,避免内存泄漏
  _refreshTimer?.cancel();
  super.dispose();
}

注意:原代码中int.parse('$snap')存在空指针风险,建议添加snapshot.hasData判断,避免数据为空时崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:45:25