繁体   English   中英

在可完成的未来中等待可完成的未来?

[英]Await completablefutures inside a completablefuture?

我正在尝试执行等待多个其他异步操作的异步操作......我究竟如何使用可完成的期货来做到这一点?

这是我想要在不调用 join 的情况下实现的目标,我实际上希望那些触发的操作彼此异步运行。

myDatabaseOperation.thenApplyAsync(){

   for(var i = 0; i < 3; i++) triggerOtherAsyncOperations();
   // Await triggered operations...

   return calculatedValueFromOperations;
}

这是我到目前为止所得到的......问题是 CompletableFuture.allOf() 没有按预期工作......它根本不会阻止异步操作并继续破坏未来。

        var queryTask = database.getAsync("select i from Identity i where i.id in "+list.toString(), Identity.class);
        var loadComponentsTask = queryTask.thenApplyAsync(identities -> {

            var loadingTasks = new HashSet<CompletableFuture<Set<Integer>>>();
            var typeIDs = HibernateComponentUtils.mergeByComponents(identities, prototypeHierachy::get);

            // Start all loading tasks
            for(var entry : typeIDs.entrySet()){

                var sqlList = HibernateQueryUtils.toSQLList(entry.getValue());
                var loadingTask = loadEntitiesAsync(entry.getKey(), " where identity.id in "+sqlList);
                loadingTasks.add(loadingTask);
            }

            // Await all started loading tasks without blocking the mainthread
            var loadingTasksArray = loadingTasks.toArray(CompletableFuture[]::new);
            CompletableFuture.allOf(loadingTasksArray);

            // Add all loaded entities from each task to a set
            var loadedEntities = new HashSet<Integer>();
            for(var task : loadingTasks) loadedEntities.addAll(task.join());
            return (Set<Integer>)loadedEntities;
        });

        return loadComponentsTask;
}

我做错了吗? 我错过了什么? 在异步操作中等待异步操作的正确方法是什么?

CompletableFuture.allOf(...)不应该阻止。 它返回一个 CompletableFuture,如果你想等待,你可以调用 join/get。

CompletableFuture.allOf(...).join();

但这不是最好的解决方案。

我认为更好的解决方案是:

 var loadComponentsTask = queryTask.thenComposeAsync(identities -> {
            ...
            return CompletableFuture.allOf(loadingTasksArray)
                .thenApply( v -> {
                   // Add all loaded entities from each task to a set
                   var loadedEntities = new HashSet<Integer>();
                   for(var task : loadingTasks) {
                           loadedEntities.addAll(task.join());
                   }
                   return (Set<Integer>) loadedEntities;
                });
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM