RxJava过滤后合并多个观察者

时间:2018-11-09 15:57:28

标签: java rx-java observable rx-java2

以下是我当前的代码

  private final List<Disposable> subscriptions = new ArrayList<>();

  for (Instrument instrument : instruments) {
    // Waiting for OrderBook to generate Reliable results.
    GenericBook Book =
        service
            .getBook(instrument.getData())
            .filter(gob -> onBookUpdate(gob))
            .blockingFirst();

    subscriptions.add(
        service
            .getBook(instrument.getData())
            .subscribe(
                gob -> {
                  try {
                    onBookUpdate(gob);
                  } catch (Exception e) {
                    logger.error("Error on subscription:", e);
                  }
                },
                e -> logger.error("Error on subscription:", e)));
  }

因此,它首先对每台仪器执行的功能是等待onBookUpdate(gob)的输出变为true。 onBookUpdate(gob)返回布尔值。 一旦我们首先将onBookUpdate设置为true,那么我将把该订阅者推送到subscriptions变量中。

这变慢了,因为我必须等待每台乐器,然后再继续下一个乐器。

我的目标是并行运行所有这些,然后等待所有完成并将其推送到subscriptions变量。

我尝试了zip,但没有用

  List<Observable<GenericOrderBook>> obsList = null;
  for (Instrument instrument : instruments) {
    // This throws nullException.
   obsList.add(service
            .getBook(instrument.getData())
            .filter(gob -> onBookUpdate(gob))
            .take(1));
    }
  }
// Some how wait over here until all get first onBookUpdate as true.
String o = Observable.zip(obsList, (i) -> i[0]).blockingLast();

2 个答案:

答案 0 :(得分:2)

使用可观察物等时,应全心全意地拥抱它们。拥抱的前提之一是将管道的配置和构造与执行分开。

换句话说,先配置管道,然后在数据可用时通过它发送数据。

此外,拥抱可观察对象意味着避免for循环。

我不是您的用例的100%,但我建议创建一个将工具作为输入并返回订阅的管道...

类似

service.getBook(instrument.getData())
 .flatMap(gob -> {
   onBookUpdate(gob);
   return gob;
});

这将返回您可以订阅的Observable并将结果添加到订阅中。

然后创建一个可观察的种子,将仪器对象泵入其中。

不确定您的API的某些细节,如果不清楚或我做错了假设,请回来找我。

答案 1 :(得分:0)

我假设instruments是一个列表。如果是,那么您可以执行以下操作

Observable
    .fromIterable(instruments)
    // Returns item from instrument list one by one and passes it to getBook()
    .flatmap(
        instrument -> getBook(instrument.getData())
    )
    .filter(
        gob -> onBookUpdate(gob)
    )
    // onComplete will be called if no items from filter 
    .switchIfEmpty(Observable.empty())
    .subscribe(
        onBookUpdateResponse -> // Do what you want,
        error -> new Throwable(error)
    );

希望这会有所帮助。