Flutter首页多API并行请求实现求助
解决方案:并行请求多个API
核心思路
用Flutter的Future.wait方法同时发起多个API请求,让它们并行执行,而非顺序等待前一个请求完成后再启动下一个。
具体实现步骤
1. 并行启动API请求
在页面初始化阶段(比如initState),同时启动两个API请求,避免互相阻塞:
方式一:独立维护两个Future(各自加载完成后渲染)
late Future<List<BannerItem>> _futureBanners; late Future<List<Product>> _futureProducts; @override void initState() { super.initState(); // 同时触发两个请求,并行执行 _futureBanners = fetchbanner(); _futureProducts = fetchProducts(); }
这样两个请求会同时发送,各自完成后更新对应的FutureBuilder,Banner和商品数据会分别加载完成后显示,不会出现先等Banner加载完才开始加载商品的情况。
方式二:用Future.wait统一管理(等待全部完成后一起渲染)
如果希望等两个请求都完成后再同步显示UI,可以合并两个Future:
late Future<List<dynamic>> _combinedFuture; @override void initState() { super.initState(); // 并行执行两个请求,等待全部完成 _combinedFuture = Future.wait([ fetchbanner(), fetchProducts(), ]); }
对应的UI层可以用一个FutureBuilder处理:
FutureBuilder<List<dynamic>>( future: _combinedFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator(color: AppColors.buttonColor)); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } else { final banners = snapshot.data![0] as List<BannerItem>; final products = snapshot.data![1] as List<Product>; // 渲染Banner和GridView组合UI return Column( children: [ // Banner组件(保留你原来的AnimatedSize等逻辑) AnimatedSize( duration: const Duration(milliseconds: 300), child: Container(/* Banner内容 */), ), // GridView组件(保留你原来的GridView.builder逻辑) Expanded( child: GridView.builder(/* 商品列表内容 */), ), ], ); } }, )
2. 关键注意事项
- 禁止在build方法中直接调用API:不要把
fetchbanner()或fetchProducts()直接写在FutureBuilder的future参数里,否则每次页面build都会重新发起请求,导致重复请求和性能问题。必须把Future赋值给成员变量,在initState中初始化。 - 错误处理保留:继续沿用你原来的错误提示逻辑,确保请求失败时能给用户反馈。
- 本地存储不影响并行:
fetchProducts里的SharedPreferences写入操作是异步的,但它只会在商品API返回后执行,不会阻塞Banner请求的并行执行。
原问题根源
你之前出现串行加载的原因,大概率是初始化时顺序等待了两个API请求(比如先await fetchbanner(),再await fetchProducts()),导致第二个请求必须等第一个完成后才会发起。改成同时启动两个Future就能让API请求并行执行,减少整体加载时间。
内容的提问来源于stack exchange,提问作者Tanu Purohit
相关产品推荐
相关产品推荐

