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

Flutter使用Future.wait合并双接口请求无返回数据问题求助

Flutter 多接口合并请求修复方案

核心问题

  • 你定义的getData异步方法无返回值,async方法无显式return时默认返回Future<void>,导致FutureBuilder的shot.data永远为null,hasData始终为false,页面一直停在加载状态
  • 请求方法定义在build方法内会导致每次页面重绘都重复发起接口请求,存在性能损耗
  • 局部变量存储的接口结果没有返回给FutureBuilder,无法在builder中拿到数据

修复代码

Future.wait会按照传入Future的顺序返回对应结果集合,正好满足你用shot.data[0]、shot.data[1]取值的需求:

class AdView extends StatefulWidget {
  const AdView({Key? key, required String id}) : super(key: key);
  final String id = '2';
  @override
  _AdViewState createState() => _AdViewState();
}

class _AdViewState extends State<AdView> {
  final _adService = NewsService();
  // 预声明组合后的Future,避免build重复触发请求
  late Future<List<dynamic>> _combinedRequest;

  @override
  void initState() {
    super.initState();
    // 按顺序组合两个请求,返回列表索引0对应AdBanner结果,索引1对应Categories结果
    _combinedRequest = Future.wait([
      _adService.getAds(widget.id),
      _adService.getAllCategories(),
    ]);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<dynamic>>(
      future: _combinedRequest,
      builder: (BuildContext context, AsyncSnapshot<List<dynamic>> shot) {
        // 先判断请求是否完成
        if (shot.connectionState == ConnectionState.done) {
          // 错误处理
          if (shot.hasError) {
            return NewsError(
              errorMessage: shot.error.toString(),
            );
          }
          // 按索引取值即可
          AdBanner adBanner = shot.data![0] as AdBanner;
          Categories categories = shot.data![1] as Categories;
          
          return ListView.builder(
            itemCount: 2,
            itemBuilder: (BuildContext context, int index) {
              // 业务逻辑可正常使用adBanner和categories对象
              return Text('当前索引:$index');
            }
          );
        }
        // 请求中返回加载态
        return const NewsLoading(
          text: 'loading...',
        );
      }
    );
  }
}

优化建议

如果不想用dynamic类型强转,可以自定义数据实体类包裹两个接口的返回结果,类型安全更高:

class AdPageData {
  final AdBanner banner;
  final Categories categories;
  AdPageData(this.banner, this.categories);
}

// 初始化Future时改为:
late Future<AdPageData> _combinedRequest;

@override
void initState() {
  super.initState();
  _combinedRequest = _fetchPageData();
}

Future<AdPageData> _fetchPageData() async {
  final results = await Future.wait([
    _adService.getAds(widget.id),
    _adService.getAllCategories(),
  ]);
  return AdPageData(results[0] as AdBanner, results[1] as Categories);
}

// FutureBuilder泛型指定为AdPageData,后续直接用shot.data?.banner、shot.data?.categories取值即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:57:04