Flutter项目中FutureBuilder工作时如何获取另一API的返回数据
Flutter 并行请求双Future结果获取实现方案
方案1:Future.wait 并行请求(推荐,总耗时为两个请求中耗时更长的那个)
你之前用Future.wait失败大概率是没有提前组合存储Future、或者类型转换处理不当,正确写法如下:
- 调整Future变量定义
// 组合两个Future,返回结果按传入顺序保存在List中 late Future<List<Object>> _futureCombined; late Future<Kategori> _futureArticles; late Future<Article> _futureSummary;
- initState中初始化请求
@override void initState() { super.initState(); _futureArticles = _newsService.getArticlesByCategory(widget.id); _futureSummary = _newsService.getArticleById(widget.id); // 并行执行两个请求,组合为单个Future _futureCombined = Future.wait([_futureArticles, _futureSummary]); }
- 调整FutureBuilder逻辑
child: FutureBuilder<List<Object>>( future: _futureCombined, builder: (BuildContext context, AsyncSnapshot<List<Object>> snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { // 自定义错误处理逻辑 return Text("请求失败: ${snapshot.error}"); } // 按顺序取出两个请求结果并做类型转换 final Kategori kategori = snapshot.data![0] as Kategori; final Article summaryArticle = snapshot.data![1] as Article; final articles = kategori.data; final summary = summaryArticle.json.summary; // 此处替换为你原有页面渲染逻辑,现在可同时使用articles和summary两个变量 return ...; } // 自定义加载中状态 return const CircularProgressIndicator(); } )
如果你的项目使用Dart 3.0+(Flutter 3.10及以上版本),可以用Record类型替代List来避免类型转换,代码更安全:
// 定义组合Future的Record类型 late Future<(Kategori, Article)> _futureCombined; // initState中组合 _futureCombined = () async { final res1 = await _newsService.getArticlesByCategory(widget.id); final res2 = await _newsService.getArticleById(widget.id); return (res1, res2); }(); // 取值时直接按属性拿,无需类型转换 final (kategori, summaryArticle) = snapshot.data!;
方案2:嵌套FutureBuilder(适合优先渲染列表的场景)
如果你不需要等两个请求都完成再渲染页面,希望列表先加载出来、摘要后显示,可以不用改现有外层FutureBuilder结构,直接在需要展示summary的位置嵌套第二个FutureBuilder:
// 原有外层FutureBuilder逻辑不变,拿到articles后渲染列表,在需要显示摘要的位置添加: FutureBuilder<Article>( future: _futureSummary, builder: (context, sumSnapshot) { if (sumSnapshot.hasData) { return Text(sumSnapshot.data!.json.summary); } else if (sumSnapshot.hasError) { return const Text("摘要加载失败"); } return const Text("加载摘要中..."); } )
关于API复用说明
第二个getArticleById方法完全可以在其他页面正常调用,每次调用都是独立的请求,和当前页面的请求互不干扰。如果要优化相同ID的重复请求,可以在_newsService中添加内存缓存逻辑,相同参数的请求在缓存有效期内直接返回缓存结果即可。
内容的提问来源于stack exchange,提问作者gegentierversuche
相关产品推荐
相关产品推荐

