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

Flutter中Dart将Stream<List<double>>转List<double>报bad state错误如何解决

问题根因与修复方案

错误触发的3个核心原因

  • 映射逻辑缺失返回值:_DeadliftWeightsList中对文档做映射的回调函数仅创建了Weights对象,但没有显式return,最终生成的weights列表全为null,后续NormalizedData中用!强制解包null直接触发异常。
  • 同步异步逻辑混淆:Stream是异步数据源,listen的回调会在未来数据到达时才执行,你在DLWeights中同步返回的weights列表在返回时为空,若后续逻辑依赖列表有值(比如调用reduce、访问首个元素等操作)就会触发bad state错误。
  • 边界条件缺失:如果查询到的文档为空、或者所有重量值相等,NormalizedData中调用reduce、执行除法运算时会直接抛出bad state、除零错误。

修复后的完整代码

1. 修复_DeadliftWeightsList映射逻辑

List<double> _DeadliftWeightsList(QuerySnapshot snapshot){
  List <Weights?> weights = snapshot.docs.map((doc){
    // 补全return语句,返回创建的Weights对象
    return Weights(
        date: doc.get('date') ?? DateTime.now(),
        weight: doc.get('deadLiftWeight') ?? 0);
  }).toList();
  final List<double> normalized = NormalizedData(weights);
  return normalized;
}

2. 修复NormalizedData边界判断

List<double> NormalizedData (List<Weights?> weights) {
  // 过滤null值,避免空指针
  final List<int> array = weights.whereType<Weights>().map((e) => e.weight).toList();
  // 空列表直接返回空,避免reduce触发bad state
  if(array.isEmpty) return [];
  final lower = array.reduce(min);
  final upper = array.reduce(max);
  // 最值相等时直接返回等长的0值列表,避免除零错误
  if(upper == lower) {
    return List.filled(array.length, 0);
  }
  final List<double> normalized = [];
  for(var i = 0 ; i < array.length; i++){
    normalized.add((array[i] - lower) / (upper - lower));
  }
  return normalized;
}

3. 修复DLWeights异步逻辑

如果需要实时监听数据变化,直接返回Stream,UI层用StreamBuilder消费即可:

Stream<List<double>> DLWeights() {
  return usersCollection.snapshots()
      .map(_DeadliftWeightsList);
}
// UI层使用示例
// StreamBuilder<List<double>>(
//   stream: DLWeights(),
//   builder: (context, snapshot) {
//     if(snapshot.hasData) {
//       final weights = snapshot.data!;
//       // 基于weights渲染对应UI
//     }
//     return CircularProgressIndicator();
//   }
// )

如果仅需要获取一次当前的重量数据,改为返回Future:

Future<List<double>> getDLWeightsOnce() async {
  final snapshot = await usersCollection.get();
  return _DeadliftWeightsList(snapshot);
}
// 调用时用await接收值即可:
// final weights = await getDLWeightsOnce();

内容的提问来源于stack exchange,提问作者Something You

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:54:04