如何在Vert.x中执行顺序的while循环

时间:2018-07-12 09:38:58

标签: mongodb vert.x

我有一个用例,例如获取项目的文件夹路径,这样的数据库架构(存储在MongoDB中)

Item table: {itemID: 100, itemName: 'Vert.X', parentID: 2}

Category table: 
{categoryId:2, categoryName:'Information System', parentID:1}
{categoryId:1, categoryName:'Books', parentID:0}

其中parentID = 0是顶级类别(类别表中没有记录)。所以我们应该有一个这样的功能

getItemPathByItemId(100) = 'ROOT > Books > Information System';

以常规方式,我可以进行while循环:

Category getCategoryByID(int categoryID);

int categoryId = 2; // get parent_id of item
StringBuilder s = new StringBuilder();
while (true) {
   Category c = getCategoryByID(categoryId);
   if (c != null) {
      s.append(c.getName());
      categoryId = c.getParentId();
   }
   else {
      break; 
   }
}

在使用VertX MongoClient进行查询时,我不知道在Vert.X中实现此功能,我有一种获取此类名称的方法

public Future<String> getCategoryName(int categoryId) {
    Future<String> future = Future.future();

    mongoClient.findOne("category", new JsonObject().put("categoryId", categoryId), null, res -> {
        JsonObject obj = res.result();
        if (obj != null) {
            future.complete(obj.getString("name"));
        }
        else {
            future.complete("ROOT");
        }
    });

    return future;      
}

我知道我们可以使用future.compose()进行顺序处理,但是不确定如何在while循环中实现这一点。谢谢大家阅读。

3 个答案:

答案 0 :(得分:1)

您快到了。您缺少的是再次递归调用函数。
 像这样:

public Future<String> getCategoryName(int categoryId) {
    Future<String> f = Future.future();
    mongoClient.findOne(categoryId, (res) -> {
        if (res != null) {
            f.complete(getCategoryName(res.parentId).result() + " > " + res.name);
        }
        else {
            f.complete("ROOT");
        }
    });
    return f;
}

我必须说,那些可能无限的循环不是期货的最佳用例,但是您可以开始使用

答案 1 :(得分:0)

CompositeFuture为您提供了构筑许多期货的方法,并在一切都完成,失败等时做出了一些贡献。

在您的情况下,all(...)看起来不错。

您还可以查看vertx-mongo模块的RxJava2绑定,以https://github.com/vert-x3/vertx-examples/blob/master/rxjava-2-examples/src/main/java/io/vertx/example/reactivex/database/mongo/Client.java为例。

答案 2 :(得分:0)

public static <T> Future<T> nonBlockingWhile(Supplier<Future<T>> supplier, Predicate<T> predicate, Integer retry) {
    return supplier.get().compose(result -> {
        if (retry <= 0 || predicate.test(result)) {
            return Future.succeededFuture(result);
        }
        return nonBlockingWhile(supplier, predicate, retry - 1);
    });
}

编写了这个通用函数,表现为无阻塞的while循环。

供应商类似于花括号代码块。 谓词类似于条件,位于while子句中。