【问题标题】:Use RxJava Flowable - how to split the emission according to the type of the event使用 RxJava Flowable - 如何根据事件类型拆分发射
【发布时间】:2021-09-16 16:53:21
【问题描述】:

假设我们使用 Firebase ChildEventListener,它可以作为多个数据源(它的函数),我用 Flowable 或 Observable 包装它。我希望在每个源中,发射器将数据发送到不同的管道,因为在每种情况下,数据都可以更改,我想以不同的方式处理它——也就是说,根据类型将发射分成几个不同的流事件。

如何在 Java 中做到这一点?

  public void newUsers() {
    DatabaseReference ref = database.getReference().child("Users");
    Flowable.create(emitter -> {
        ref.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                User userData = dataSnapshot.getValue(User.class);
                emitter.onNext(userData);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
             User userData = dataSnapshot.getValue(User.class);
                emitter.onNext(userData);
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
             User userData = dataSnapshot.getValue(User.class);
                emitter.onNext(userData);
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                emitter.onNext(userData);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
             User userData = dataSnapshot.getValue(User.class);
                emitter.onNext(userData);
            }
        });
    }
}

【问题讨论】:

  • 你不会使用不同的发射器来拥有多个流吗?
  • 我很乐意这样做,但我不知道是否可以将 ChildEventListener 的功能分开,以便 Flowable 将所有功能包装在一起。你知道怎么做吗? @鲨鱼
  • 是的,当然。让我重构这件事……不知道这是否是正确的方法,但这是我首先尝试的,而不是单个可流动的。
  • 发布了一些东西,考虑一下@nirkov

标签: java firebase rx-java


【解决方案1】:

因此,要拥有多个流,我们不能只有一个 Flowable。我不知道 Flowable 是否真的是一个要求,所以我将概述我的想法,您可以随意更正它并适应您的需求。

   BehaviourSubject childAddedStream;
   BehaviourSubject childChangedStream;
   BehaviourSubject childRemovedStream;
   BehaviourSubject childMovedStream;
   BehaviourSubject cancelledStream;

  public void newUsers() {
    DatabaseReference ref = database.getReference().child("Users");
    
    ref.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                User userData = dataSnapshot.getValue(User.class);
                childAddedStream.onNext(userData);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
             User userData = dataSnapshot.getValue(User.class);
             childChangedStream.onNext(userData);
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
             User userData = dataSnapshot.getValue(User.class);
             childRemovedStream.onNext(userData);
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            childMovedStream.onNext(userData);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
             User userData = dataSnapshot.getValue(User.class);
             cancelledStream.onNext(userData);
            }
        });
    }
}

这样的事情将是我的起点。

这个想法是让这个类为每个回调初始化不同的主题,在创建回调时将回调注册到 FirebaseDatabase,并将各个回调路由到不同的流(主题,请随意使用更相关的主题,而不是 BehaviourSubject,如果你want) - 那么需要监听的人只需监听相关的流而不是单个 Flowable,后者就像回调和反应世界之间的桥梁。

【讨论】:

  • 或者,您可以采用与您的想法类似的方法 - 但您需要 5 个可流动对象,并且让它们中的每一个只监听(并发出)一个回调。
  • 或者,您发送Pair<UserData, EventType> 并仅使用一个可流动的 - 并通过过滤 EventType 枚举 - 例如REMOVED, CHANGED, MOVED, ADDED,您可以获得多个流。在这种情况下,我仍然认为您需要一个主题,但一个主题可以通过过滤为所有这五个流提供服务。
  • 如果一个发出一对,你就不需要多个流;根据EventType 过滤一个流将生成多个共享相同支持数据的流。您要么使用单个 Subject/Flowable 发射一对(并通过过滤获得多个流),要么每个回调都有一个 Subject/Flowable。就是这么简单。
  • 如果您使用 EventType 枚举事物(并发出一对) - 您的事物已经很好,只需要适当的枚举与 UserData 一起使用,因此消费者可以按事件区分并过滤在适当的 EventType 上。
  • cc @nirkov(ping,因为你不会看到我的帖子上的评论)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多