How do you access completed futures passed to CompletableFuture allOf?

后端 未结 1 546
旧巷少年郎
旧巷少年郎 2020-12-30 12:15

I am trying to get a grip of Java 8 CompletableFuture. How can I join these to person and return them after \"allOf\". The code under is not working but gives you an idea of

相关标签:
1条回答
  • 2020-12-30 12:51

    The CompletableFuture#allOf method does not expose the collection of completed CompletableFuture instances that were passed to it.

    Returns a new CompletableFuture that is completed when all of the given CompletableFutures complete. If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture also does so, with a CompletionException holding this exception as its cause. Otherwise, the results, if any, of the given CompletableFutures are not reflected in the returned CompletableFuture, but may be obtained by inspecting them individually. If no CompletableFutures are provided, returns a CompletableFuture completed with the value null.

    Note that allOf also considers futures that were completed exceptionally as completed. So you won't always have a Person to work with. You might actually have an exception/throwable.

    If you know the amount of CompletableFutures you're working with, use them directly

    CompletableFuture.allOf(p1, p2).thenAccept(it -> {
        Person person1 = p1.join();
        Person person2 = p2.join();
    });
    

    If you don't know how many you have (you're working with an array or list), just capture the array you pass to allOf

    // make sure not to change the contents of this array
    CompletableFuture<Person>[] persons = new CompletableFuture[] { p1, p2 };
    CompletableFuture.allOf(persons).thenAccept(ignore -> {
       for (int i = 0; i < persons.length; i++ ) {
           Person current = persons[i].join();
       }
    });
    

    If you wanted your combinePersons method (ignoring it's a @Test for now) to return a Person[] containing all the Person objects from the completed futures, you could do

    @Test
    public Person[] combinePersons() throws Exception {
        CompletableFuture<Person> p1 = CompletableFuture.supplyAsync(() -> {
            return new Person("p1");
        });
    
        CompletableFuture<Person> p2 = CompletableFuture.supplyAsync(() -> {
            return new Person("p1");
        });
    
        // make sure not to change the contents of this array
        CompletableFuture<Person>[] persons = new CompletableFuture[] { p1, p2 };
        // this will throw an exception if any of the futures complete exceptionally
        CompletableFuture.allOf(persons).join();
    
        return Arrays.stream(persons).map(CompletableFuture::join).toArray(Person[]::new);
    }
    
    0 讨论(0)
提交回复
热议问题