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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:25:20