将Stream<List<Habit>>映射为目标类型时返回Stream<Null>的问题求助
问题分析与修复
核心错误点
- 外层回调缺少返回值:
habitsStream.map的回调里执行了habitsList.map(...).toList()但未返回该结果,导致回调默认返回void,最终result类型变为Stream<Null>。 - 异步操作未正确处理:内层
habitsList.map的回调使用async后,每个元素会返回Future<HabitCompletionViewModel>,直接toList()得到的是List<Future<...>>,而非预期的同步ViewModel列表,必须通过Future.wait等待所有异步任务完成。 - Stream异步转换方式错误:回调包含异步逻辑时,不能直接用
Stream.map,需用Stream.asyncMap处理返回Future的回调,确保Stream输出类型正确。
修复后的代码
Stream<List<HabitCompletionViewModel>> _getTodaysHabits( Stream<List<Habit>> habitsStream) { return habitsStream.asyncMap((habitsList) async { // 等待所有异步转换任务完成,得到同步的ViewModel列表 return Future.wait(habitsList.map((habit) async { await _getHabitCompletionsCurrent(habit); HabitCompletion completion = habit.completions!.firstWhere( (completion) => completion.date .dayEqualityCheck(DateTime.now().startOfDate())); return HabitCompletionViewModel(completion: completion, habit: habit); })); }); }
关键修改说明
- 替换
map为asyncMap:自动处理返回Future的回调,将Stream<Future<List<...>>>转换为符合要求的Stream<List<HabitCompletionViewModel>>。 - 补充返回逻辑:通过
Future.wait等待所有内层异步任务完成,确保回调返回正确的ViewModel列表。 - (可选优化)建议对
firstWhere添加异常处理,比如使用firstWhereOrNull,避免因未找到对应日期的completion导致整个Stream中断。
内容的提问来源于stack exchange,提问作者Charlie Page
相关产品推荐
相关产品推荐

