Rx Observables:为每个原始项目发出附加项目,将它们减少为另一种类型,消耗

时间:2015-12-13 21:53:20

标签: java couchbase rx-java observable couchbase-java-api

使用Couchbase Java客户端2.2.2和Rx Observables 1.0.15进行以下操作时遇到问题:

  • 我有一个文件名列表
  • 除了文档名称的每个原始文档,我想加载另一个文档(从原始文档名称推断),因此我将获得一对文档。如果这两个文件中的任何一个不存在,请不要再使用这个文件。
  • 如果该对有效(即两个文档都存在),则使用这两个文档从中创建自定义对象
  • 将这些已转换的项目合并到一个列表中

到目前为止,我所提出的看起来真的很有意义:

List<E> resultList = new ArrayList<>();

Observable
    .from(originalDocumentNames)
    .flatmap(key -> {
        Observable firstDocument = bucket.async().get(key);
        Observable secondDocument = bucket.async().get(getSecondKeyNameFrom(key));
        return Observable.merge(firstDocument, secondDocument);
    })
    .reduce((jsonDocument1, jsonDocument2) -> {
        if (jsonDocument1 == null || jsonDocument2 == null) {
            return null;
        }
        resultList.add(createCustomObject(jsonDocument1, jsonDocument2);
        return null;
    })
    .filter(Objects.nonNull)
    .singleOrDefault(null)
    .subscribe(new Subscriber<E>() {
        public void onComplete() {
            //use resultList in a callback function
        }
    });

这不起作用。我不知道在哪里,但我认为我正在以错误的方式使用Observable.merge。 另外我认为我正以错误的方式接近整个问题。

所以主要问题似乎是:

  • 如何向Observable流发出附加项?
  • 如何将两件物品减少为另一种物品? (减少(T,T,T)不允许)
  • 我错了吗?

2 个答案:

答案 0 :(得分:4)

您可以在平面图中使用zip 。 Zip将使用最少的项目发出与Observable一样多的项目。因此,如果缺少其中一个文档,其序列将为空,zip将跳过它。

Observable
.from(originalDocumentNames)
.flatmap(key -> {
    //the stream of 0-1 original document
    Observable firstDocument = bucket.async().get(key);
    //the stream of 0-1 associated document
    Observable secondDocument = bucket.async().get(getSecondKeyNameFrom(key));

    //using zip and the createCustomObject method reference as a zip function to combine pairs of documents
    return Observable.zip(firstDocument, secondDocument, this::createCustomObject);
})
.toList() //let RxJava aggregate into a List
.subscribe(
    //the "callback" function, onNext will be called only once with toList
    list -> doSomething(list), 
    //always try to define onError (best practice)
    e -> processErrors(e)
);

答案 1 :(得分:1)

此代码中有几个问题:

  1. 副作用,ix = 1; for hx = findall(0, 'type', 'figure')' figname = get(hx, 'Name'); if ~isequal(handles.appName, figname) figure(hx); figname = ['figure_' num2str(ix) '.jpg']; saveas(hx, figname , 'jpg'); end end 操作正在添加到reduce链外的列表,这是错误的。由于Rx具有Observable操作,reduce应该返回列表或者根本不存在。同样由于返回toList的reduce操作,下一个操作必须处理它;这是相当不优雅的。

  2. null操作错误,您应该在mergezip并构建配对/聚合。

  3. 可选点:如果get操作将返回多个项目,那么 flatmap 操作将无法处理(可能是事实上使用couchbase的情况)

  4. 注意我没有IDE,所以现在没有代码。但在我的观点中,将flatmap替换为merge并删除zip肯定会有所帮助。