Flutter异步执行顺序异常:首次SessionScreen数据为空问题排查
解决方案
1. 等待数据加载完成再启动SessionScreen
不要在数据加载过程中直接跳转页面,先完成JSON读取和随机列表生成,再导航到SessionScreen。示例代码(以Flutter为例):
// SessionController中处理数据加载的异步方法 Future<List<QuizItem>> loadAndGenerateQuizList() async { // 读取本地JSON文件 final String response = await rootBundle.loadString('assets/quiz_data.json'); final List<dynamic> rawData = json.decode(response); // 生成随机8项列表 final shuffledData = rawData.shuffled(); return shuffledData.take(8).map((item) => QuizItem.fromJson(item)).toList(); } // 启动会话的方法 void startSession(BuildContext context) async { final quizList = await loadAndGenerateQuizList(); if (quizList.isNotEmpty) { Navigator.push(context, MaterialPageRoute(builder: (_) => SessionScreen(quizList: quizList))); } }
2. 在SessionScreen内处理加载状态
如果必须提前进入SessionScreen,就在页面中加入加载状态逻辑,等数据就绪后再渲染内容:
class SessionScreen extends StatelessWidget { final Future<List<QuizItem>> quizListFuture; const SessionScreen({super.key, required this.quizListFuture}); @override Widget build(BuildContext context) { return FutureBuilder<List<QuizItem>>( future: quizListFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text('加载失败,请重试')); } else { return QuizContent(quizList: snapshot.data!); } }, ); } }
调用时直接传入加载Future:
Navigator.push(context, MaterialPageRoute(builder: (_) => SessionScreen(quizListFuture: loadAndGenerateQuizList())));
3. 修复预加载逻辑的复用问题
如果已经做了App启动阶段预加载,要确保缓存的数据被正确复用:
- 将预加载的JSON数据缓存到全局单例或状态管理容器(如Provider、Riverpod)中,SessionController直接读取缓存,不再重复加载
- 确认预加载在App启动时真正完成,比如在
main方法中等待预加载完成再启动App:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 预加载并缓存数据 await QuizDataCache.preload(); runApp(const MyApp()); }
SessionController直接从缓存取数据生成列表:
List<QuizItem> generateQuizList() { final cachedData = QuizDataCache.getCachedData(); return cachedData.shuffled().take(8).toList(); }
4. 排查状态管理的更新通知
如果使用了状态管理工具,确保数据准备完成后,状态更新能触发SessionScreen的重建:
- 比如用Riverpod时,将数据加载状态设为异步,SessionScreen监听该状态变化
- 避免初始化时给状态赋空列表,而是先设置“加载中”状态,等数据就绪后再更新为有效列表
内容的提问来源于stack exchange,提问作者egm_along
相关产品推荐
相关产品推荐

