【问题标题】:How to load relationed objects with RxJava如何使用 RxJava 加载相关对象
【发布时间】:2016-11-30 09:58:23
【问题描述】:

假设我也有这些课程

class Event {
  int id;
  String name;
  List<Integer> facilityIds;
  List<Facility> facilities; // Empty, the one I need to load
}

class Facility {
  int id;
  String name;
}

目标:打印出每个事件及其设施的名称。

约束RxJava2,Facilities 只能一一加载(getFacility(facilityId)

来自Observable&lt;Event&gt;,我无法找到加载设施并将它们设置回各自事件的方法。

基本上我在想这样的事情:

Observable<Event> events;
events
  .map(Event::getFacilityIds)
  .flatMap(Observable::fromIterable)
  .map(facilityId -> service.getFacility(facilityId))
  . // somehow get the event reference and
    // so some event.addFacility() or something similar

然后我失明了,无法找到将它们链接回事件的方法。我还考虑过使用zip,这可能是一个解决方案,但我没有找到一种方法来保留和事件引用,以便以后为它们设置设施。

什么是反应式方法?任何提示将不胜感激。

【问题讨论】:

    标签: java system.reactive rx-java2


    【解决方案1】:

    forEach 怎么样?

    events.forEach(event -> Observable.fromIterable(event.facilityIds)
                //or just .map(service::getFacility)
                .map(facilityId -> service.getFacility(facilityId)
                .forEach(facility -> event.facilities.add(facility)))
    

    如果您想继续 流。
    这将在前一个运算符的线程上同步执行。

    如果您getFacility 花费了宝贵的时间,您可以与flatMap 并行检索:

    events.doOnNext(event -> Observable.fromIterable(event.facilityIds)
                .flatMap(facilityId -> 
                        Observable.fromCallable(() -> service.getFacility(facilityId))
                        .subscribeOn(Schedulers.computation()))
                .blockingSubsribe(facility -> event.facilities.add(facility)))
    

    但在这种情况下,不能保证结果facilities 的顺序。

    【讨论】:

    • 使用 flatMap 而不是 map 不是更好吗?因为我认为service.getFacility 可能需要一些时间才能回复...
    • @oliv37 是的,你是对的。我将提供并行版本。你知道在并行执行的情况下如何保证启动顺序吗?因为我从未尝试过。
    • 我得到了一个稍微不同的解决方案,但是您对 forEach 的使用让我走上了正确的道路,谢谢。
    • forEach 正在从 Rx 世界走向命令式。你应该尽量避免forEachsubscribetoList等,以保持Rx的精神。
    【解决方案2】:

    有一个包含事件和 id 的元组或中间类。

    events
      .flatMap(evt -> Observable::fromIterable(Event::getFacilityIds(evt)).map(id -> new Tuple(evt, id)))
    

    捕获时它必须在范围内。

    public class Tuple<X, Y> { 
      public final X x; 
      public final Y y; 
      public Tuple(X x, Y y) { 
        this.x = x; 
        this.y = y; 
      } 
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多