如何做一个 switchmap 或任何更好的方法来替换 RxDart 中的值

Posted

技术标签:

【中文标题】如何做一个 switchmap 或任何更好的方法来替换 RxDart 中的值【英文标题】:How to do a switchmap or any better way to replace values in RxDart 【发布时间】:2021-04-03 02:23:35 【问题描述】:

我有一个包含聊天室信息的集合。像这样的:


  chatroomid: 59,
  members: [2,3]

现在我要做的是,获取集合流,在此过程中,能够根据成员 ID 将成员字符串 ID 替换为相应的 Firestore 文档。

最终结果应如下所示:


chatroomid: 59,
members: [
  id: 2,
  username: Johndoe1
,

  id: 3,
  username: Jennydoe1
]

Dart RxDart 可以做到这一点吗? 尝试这样的事情失败了:

  getChatroomStream(chatroomid)
  .switchMap((i) 
    return Stream.value(i.members.map((e) => i.members.add(Document(path: 'Global.userRef/$e').streamData())));
  )
  
  .listen((event) print(event);); 

[VERBOSE-2:ui_dart_state.cc(177)] 未处理的异常:并发 迭代期间的修改:实例 'MappedListIterable'。 #0 ListIterator.moveNext (dart:_internal/iterable.dart:337:7)

【问题讨论】:

【参考方案1】:
class MemberInfo 
  final int id;
  final String? username;
  final bool isLoading;


class Room 
  final int chatroomid;
  final List<int> members;


class RoomWithMemberInfos 
  final int chatroomid;
  final List<MemberInfo> infos;

  factory RoomWithMemberInfos.initial(Room room) 
     return RoomWithMemberInfos(
       room.chatroomid,
       room.members
         .map((id) => MemberInfo(id, null, true))
         .toList(growable: false)
     );
  

  RoomWithMemberInfos withInfo(MemberInfo info) 
      return RoomWithMemberInfos(
        chatroomid,
        infos
         .map((e) => e.id == info.id ? MemberInfo(e.id, info.name, false) : e)
         .toList(growable: false)
      );
  


Stream<MemberInfo> getMemberInfo(int id)  ... 

getChatroomStream()
  .switchMap((Room room) 
      final initial = RoomWithMemberInfos.initial(room);
      return Stream
         .fromIterable(room.members)
         .flatMap(getMemberInfo)
         .scan<RoomWithMemberInfos>(
            (acc, info) => acc!.withInfo(info),
            initial,
         )
         .startWith(initial);
  );

【讨论】:

以上是关于如何做一个 switchmap 或任何更好的方法来替换 RxDart 中的值的主要内容,如果未能解决你的问题,请参考以下文章

RxJS mergeMap和switchMap

使用SwitchMap()处理取消先前的请求

具有多个参数的 MediatorLiveData 或 switchMap 转换

map() 和 switchMap() 方法有啥区别?

如何以及在何处使用 Transformations.switchMap?

如何做一个perl可变长度正面lookbehind或类似的东西[复制]