首页 > 解决方案 > Vertx 复合未来

问题描述

我正在研究一个解决方案,我使用 vertx 3.8.4 和 vertx-mysql-client 3.9.0 进行异步数据库调用。

这是我一直试图以适当的反应方式解决的场景。

我有一些处于非活动状态的主表记录。我运行查询并从数据库中获取记录列表。

我这样做了:

Future<List<Master>> locationMasters = getInactiveMasterTableRecords ();

 locationMasters.onSuccess (locationMasterList -> {

            if (locationMasterList.size () > 0) {
                uploadTargetingDataForAllInactiveLocations(vertx, amazonS3Utility, 
                 locationMasterList);
            }
        });

现在在 uploadTargetingDataForAllInactiveLocations 方法中,我有一个项目列表。

我要做的是,我需要遍历这个列表,对于每个项目,我需要从 aws 下载一个文件,解析文件并将这些数据插入到 db。

我了解使用 CompositeFuture 的方法。

vertx 开发社区的人可以帮助我解决这个问题或提供一些可用的文档吗?

我没有通过谷歌搜索找到这方面的好内容。

标签: vert.x

解决方案


我正在回答这个问题,因为我正在寻找类似的东西,我最终花了一些时间才找到答案,希望这可能对其他人有用。

我相信只有当你想同步多个动作时,你才想在 vertx 中使用 CompositeFuture。这意味着您要么希望在构建复合未来的所有其他动作成功至少一个构建复合未来的动作成功的情况下执行一个动作。在第一种情况下我会使用CompositeFuture.all(List<Future> futures),在第二种情况下我会使用CompositeFuture.any(List<Future> futures).

根据您的问题,下面是一个示例代码,其中包含项目列表,对于每个项目,我们运行一个异步操作(即downloadAnProcessFile()),它返回一个 Future 并且我们希望在所有异步操作都成功doAction()的情况下执行一个操作:

    List<Future> futures = new ArrayList<>();
    locationMasterList.forEach(elem -> {
        Promise<Void> promise = Promise.promise();
        futures.add(promise.future());
        Future<Boolean> processStatus = downloadAndProcessFile(); // doesn't need to be boolean
        processStatus.onComplete(asyncProcessStatus -> {
            if (asyncProcessStatus.succeeded()){
                // eventually do stuff with the result
                promise.complete();
            } else {
                promise.fail("Error while processing file whatever");
            }
        });
    });

    CompositeFuture.all(futures).onComplete(compositeAsync -> {
        if (compositeAsync.succeeded()){
            doAction();   // <-- here do what you want to do when all future complete
        } else {
            // at least 1 future failed
        }
    });

这个解决方案可能并不完美,我想可以改进,但这是我发现的适合我的方法。希望会为别人工作。


推荐阅读