您如何访问传递给 CompletableFuture allOf 的已完成期货?

How do you access completed futures passed to CompletableFuture allOf?

我正在尝试掌握 Java 8 CompletableFuture。在 "allOf" 之后,我如何才能将这些加入到 person 和 return 中。下面的代码不起作用,但可以让您了解我尝试过的内容。

在 javascript ES6 中我会做

Promise.all([p1, p2]).then(function(persons) {
   console.log(persons[0]); // p1 return value     
   console.log(persons[1]); // p2 return value     
});

到目前为止我在 Java 的努力

public class Person {

        private final String name;

        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

@Test
public void combinePersons() throws ExecutionException, InterruptedException {
    CompletableFuture<Person> p1 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture<Person> p2 = CompletableFuture.supplyAsync(() -> {
        return new Person("p1");
    });

    CompletableFuture.allOf(p1, p2).thenAccept(it -> System.out.println(it));

}

CompletableFuture#allOf 方法不会公开传递给它的已完成 CompletableFuture 实例的集合。

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.

请注意,allOf 也将异常完成的期货视为已完成。所以你不会总是有一个 Person 可以使用。您实际上可能有一个 exception/throwable.

如果您知道正在使用的 CompletableFuture 的数量,请直接使用它们

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

如果您不知道自己有多少(您正在使用数组或列表),只需捕获您传递给 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();
   }
});

如果你想要你的 combinePersons 方法(暂时忽略它是一个 @Test)到 return 一个包含所有 Person 对象的 Person[]完成期货,你可以做

@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);
}