Как вызвать функцию без параметров после CompletableFuture.allOf - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть асинхронная функция в Java.Я хочу сделать асинхронные вызовы для ряда API (параллельно), а затем создать ответ.Поскольку мне нужны разные результаты, я хочу сохранить их в классе.У меня есть вспомогательные функции для вызова внешних API (классы с функцией вызова, которые возвращают CompletableFuture<List<T>>).Я могу сделать это следующим образом:

public class MyAction{
   private List<Bar> bars;
   private List<Baz> bazs;

   public CompletableFuture<Foo> run() {
       CompletableFuture<Void> fetchBars = new BarFetcher().call().thenAccept(this::populateBars);
       CompletableFuture<Void> fetchBazs = new BazFetcher().call().thenAccept(this::populateBazs);

       return CompletableFuture.allOf(fetchBars, fetchBazs).thenApply(this::getFoo);
   }

   private void populateBars(final List<Bar> bars) {
       this.bars = bars;
   }

   private void populateBaz(final List<Baz> bazs) {
       this.bazs = bazs;
   }

   private Foo getFoo(final Void dummy) {
       return new Foo(bars, bazs);
   }
}

Но мне пришлось добавить ненужный параметр (final Void dummy) в функцию getFoo, чтобы она заработала.Могу ли я избежать этого?если действительно должно быть getFoo(), а не getFoo(final Void dummy).Можно ли как-то дождаться завершения нескольких фьючерсов, а затем связать их в другой функции, не передавая ей напрямую какие-либо данные?

Примечание. В примере есть только два начальных вызова для извлечения данных (fetchbars и fetchBazs).) до окончательной обработки (getFoo).Однако у меня на самом деле будет больше двух.У меня в настоящее время есть три, но это может увеличиться на один или два больше.Я хотел бы выполнить все начальные вызовы параллельно, а затем завершить окончательную обработку.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Используйте правильный инструмент для работы.Чтобы объединить два фьючерса, просто используйте

public CompletableFuture<Foo> run() {
    return new BarFetcher().call().thenCombine(new BazFetcher().call(),
        (List<Bar> bars, List<Baz> bazs) -> new Foo(bars, bazs));
}

или еще проще

public CompletableFuture<Foo> run() {
    return new BarFetcher().call().thenCombine(new BazFetcher().call(), Foo::new);
}
0 голосов
/ 04 декабря 2018

вы можете изменить использование ссылки на метод на лямбду следующим образом:

return CompletableFuture.allOf(fetchBars, fetchBazs)
                        .thenApply(e -> getFoo());

тогда вам не нужно вводить фиктивный параметр.


Примечание, яЯ не настолько знаком с API CompletableFuture, поэтому, возможно, есть более подходящие решения.

...