Flutter中initState内异步方法异常:fetchEvent无法获取getUsers填充的users列表
问题根因
- 你在initState中直接顺序调用两个异步方法时,不会等待前一个方法的异步逻辑执行完成再启动后一个方法,两个方法的异步任务是并行执行的,不存在先后依赖关系
getUsers方法仅监听了用户流,但没有返回异步完成的通知,你无法感知users列表什么时候完成填充fetchEvent方法获取到活动数据、构建下拉组件时,用户流的监听回调还未触发,因此拿到的是空的users列表。热重载会触发组件重建,此时users已经完成填充,所以下拉组件恢复正常。
解决方案
方案1:串行执行两个异步任务,确保用户列表加载完成后再拉取活动数据
首先修改getUsers方法,返回异步任务完成的Future:
Future<void> getUsers() async { usersStream = authBloc.getUsers(); // 等待第一次流数据返回,完成列表填充后再结束方法 final allUsers = await usersStream.first; for (ApplicationUser user in allUsers) { users.add(user.username); } }
修改initState中的调用逻辑,等待getUsers完成后再调用fetchEvent:
@override void initState() { super.initState(); getUsers().then((_) => fetchEvent()); // 也可以用匿名async方法包裹await实现: // () async { // await getUsers(); // await fetchEvent(); // }(); }
方案2:并行加载两个资源,用户列表更新后自动刷新UI
如果希望同时拉取用户和活动数据提升加载速度,可以在用户流的监听回调中触发UI重建,自动更新下拉组件的数据源:
getUsers() async { usersStream = authBloc.getUsers(); usersStream.listen((allUsers) { // 先清空旧数据避免重复 users.clear(); for (ApplicationUser user in allUsers) { users.add(user.username); } // 组件已挂载的情况下触发刷新 if(mounted) setState(() {}); }); }
规范建议
如果项目使用BLoC架构,更推荐通过BlocBuilder监听用户状态和活动状态,由状态驱动UI构建,无需手动维护变量、处理异步依赖。
内容的提问来源于stack exchange,提问作者mame
相关产品推荐
相关产品推荐

