简体   繁体   中英

Java List of CompletableFutures to CompletableFuture List with allOf()

I have a piece of asynchronous code which contains more methods and I need to make it return CompletableFuture<List> in the end.

I need to use 2 methods:

  1. the first method getConfigsByType() returns a Flux of type Config
  2. the second one, which needs to be applied to every individual Config object, returns CompletableFuture of type Config.

I want to use allOf() in order to get the expected result, but I have an error and I do not know why: "no instance(s) of type variable(s) U exist so that Boolean conforms to CompletionStage". The error is at this line: .thenCompose(segmentedConfig -> finalEvents.add(segmentedConfig));

private CompletableFuture<List<Config>> getConfigs(User user) {

Queue<Config> finalEvents = new ConcurrentLinkedQueue<>();
List<CompletableFuture<Config>> completableFutureList =  admin.getConfigsByType(configurationProperties.getEvents()) // returns Flux<Config>
                .map(config -> {
                    return segmentConfig(config, user) // returns CompletableFuture<Config>
                            .thenCompose(segmentedConfig -> finalEvents.add(segmentedConfig));
                })
                .collect(Collectors.toList()); 

return allOf(completableFutureList)
                .thenApply(list -> finalEvents);

private CompletableFuture<Void> allOf(List<CompletableFuture<Config>> futuresList) {
        return CompletableFuture.allOf(futuresList.toArray(new CompletableFuture[0]));
    }

    private CompletableFuture<Config> segmentConfig(Config config, User user) {
        return configurationApi.getSegmentedConfig(new DefaultCombinedConfigProvider<>(config), user);
    }

What am I doing wrong?

You can not produce the list of results before the future created by allOf(completableFutureList) has been completed. Further, a Queue<Config> won't become a List<Config> .

So, remove your attempt to produce the result list from the stream operation that produces the List<CompletableFuture<Config>> . Then, add an actual operation producing the result list to allOf(completableFutureList) .

private CompletableFuture<List<Config>> getConfigs(User user) {
  List<CompletableFuture<Config>> completableFutureList
      = admin.getConfigsByType(configurationProperties.getEvents())
          .map(config -> segmentConfig(config, user))
          .collect(Collectors.toList());

  return CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[0]))
      .thenApply(voidArg -> completableFutureList.stream()
          .map(CompletableFuture::join)
          .collect(Collectors.toList()));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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