How to avoid invoking CompletableFuture.thenCompose(x -> x)?

只愿长相守 提交于 2021-02-07 10:45:31

问题


I get the feeling that I am misusing the CompletableFuture API.

When invoking CompletableFuture.exceptionally() I routinely find myself needing to invoke another asynchronous process, which means that exceptionally() returns CompletableFuture<CompletableFuture<T>> instead of CompletableFuture<T>. I then cast the result back using thenCompose(x -> x).

Here is a concrete example:

CompletableFuture<Void> listenersNotified = CompletableFuture.supplyAsync(() -> 
{
  int result = expensiveOperation();
  List<CompletionStage<Void>> futures = new ArrayList<>();
  for (EventListener listener: listeners)
    listener.onSuccess(result);
  return futures;
}).thenCompose(futures -> CompletableFuture.allOf(futures)).
  exceptionally((exception) -> 
  {
    List<CompletionStage<Void>> futures = new ArrayList<>();
    for (EventListener listener: listeners)
      futures.add(listener.onError(result));
    return CompletableFuture.allOf(futures);
  }).thenCompose(x -> x);

I understand that in the above example, one can return futures from inside exceptionally() and move thenCompose() after exceptionally() and this will work, but in real-life I don't always want to apply the same function to the result of thenSupply() as the result of exceptionally(). I want each section to take care of converting its own return type from a CompletableFuture to a synchronous value.

Is there a way to avoid falling into this pattern?

来源:https://stackoverflow.com/questions/51217350/how-to-avoid-invoking-completablefuture-thencomposex-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!