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

如何在Dart(RxDart)中将流的项收集为列表并通过另一个流暴露

问题描述

我定义了一个广播类型的StreamController:

final _controller = StreamController<List<LoadedPage<int, Entity>>>.broadcast();

还有一段获取分页数据并发送到流中的代码:

void getPagingData() async {
  final response = _api.getData(...);
  final pages = _convertResponseToPadingData(response);
  // 发送的pages结构示例:
  // <LoadedPage<int, Entity>>[
  //   LoadedPage(data: <Entity>[...]),
  //   LoadedPage(data: <Entity>[...]),
  //   LoadedPage(data: <Entity>[...]),
  // ]
  _controller.add(pages);
}

现在需要实现一个entities getter,把流中每个事件里所有LoadedPage的data属性中的Entity项,合并成单个List<Entity>,再通过Stream<List<Entity>>暴露出去。比如3个页面各包含30个Entity,最终要输出一个包含90个Entity的列表到广播流中。

需要完成的代码:

Stream<List<Entity>> get entities {
  // 此处需要将Stream<List<LoadedPage<int,Entity>>>
  // 转换为Stream<List<Entity>>
}
解决方案

可以通过Stream.map结合列表展开操作来实现,核心是把每个分页列表事件转换成扁平化的实体列表:

完整实现

Stream<List<Entity>> get entities {
  return _controller.stream.map((pages) {
    // 遍历所有页面,取出每个页面的data列表并合并成一个大列表
    return pages.expand((page) => page.data).toList();
  });
}

简洁写法

如果喜欢更紧凑的代码,也可以用箭头函数:

Stream<List<Entity>> get entities => 
    _controller.stream.map((pages) => pages.expand((page) => page.data).toList());

代码说明

  • Stream.map:对流中的每个事件(即List<LoadedPage>)进行转换,生成新的流事件
  • pages.expand((page) => page.data):将每个页面的data列表展开,把多个小列表合并成一个连续的可迭代对象
  • toList():将可迭代对象转换为List<Entity>,作为新的流事件发送

这样每次_controller发送分页数据时,entities流就会自动输出合并了所有页面实体的完整列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:26:02