Rx-Java,在同步后调用并行异步

时间:2015-04-17 17:25:15

标签: rx-java

我有几个简单的java类,如下所示:

 public class Parent {
    public String id;
    public String name;
    public List<String> childIds;
 }

 private class Child {
    public String id;
    public String name;
 }

 private class Output {
    public String name;
    public List<String> childNames;
 }

我想向rx-java发送父ID列表。对于每个父Id,rx需要获取父对象,然后对于父对象中的每个子id,获取子对象。最后,填写输出对象并将其返回。

我遇到问题的部分是获取子对象的调用需要并行完成。这是我到目前为止所拥有的。我使用collect函数将子元素添加到输出中(子元素使用Async.from)。对于我想要做的事情,这似乎相当复杂。这是最好的方法吗,还是有更好的方法?

  private class ToOutput implements Func1<Parent, Observable<Output>> {
    private Observable<Child> getChildren(Parent p) {
      Observable<String> childIds = Observable.from(p.childIds);
      return childIds.flatMap(new Func1<String, Observable<Child>>() {

        @Override
        public Observable<Child> call(String sku) {
          return Async.fromCallable(new ToChild(sku), Schedulers.io());
        }
      });
    }

    @Override
    public Observable<Output> call(final Parent p) {

      Func0<Output> initialState = new Func0<Output>() {
        @Override
        public Output call() {
          final Output output = new Output();
          output.name = p.name;
          output.childNames = new ArrayList<String>();
          return output;
        }
      };

      Observable<Child> oChildren = getChildren(p);
      Observable<Output> output = oChildren.collect(initialState, new Action2<Output, Child>() {
        @Override
        public void call(Output output, Child child) {
          output.childNames.add(child.name);
        }
      });
      return output;
    }
  }

  @Test
  public void test1() throws Exception {
    Observable<String> ids = Observable.just("1", "2", "3");
    Observable<Parent> parents = getParent(ids);
    Observable<Output> output = parents.flatMap(new ToOutput());
    ... do something with output;
  }

1 个答案:

答案 0 :(得分:0)

您可以定义方法

,而不是使用Async.fromCallable
Observable<Child> getChild(String childId)

基本上执行ToChild.call目前的工作。

然后在flatMap中,您可以使用subscribeOn(Schedulers.io())来获得并行性:

Observable<Child> getChildren(Parent p) {
    return Observable.from(p.childIds)
        .flatMap(new Func1<String, Observable<Child>>() {
            public Observable<Child> call(String childId) {
                return getChild(childId).subscribeOn(Schedulers.io());
            }
        });
}

ToOutput中,您可以从toList()运算符中受益,而不是自己实现它:

class ToOutput implements Func1<Parent, Observable<Output>> {
    public Observable<Output> call(final Parent p) {
        return getChildren(p)
            .map(new Func1<Child, String>() {
                public String call(Child c) {
                    return c.name;
                }
            })
            .toList()
            .map(new Func1<List<String>, Output>() {
                public Output call(List<String> l) {
                    return new Output(p.name, l);
                }
            });
    }
}