java CompletableFuture 的分离异常处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37032990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:07:52  来源:igfitidea点击:

Separated exception handling of a CompletableFuture

javajava-8completable-future

提问by xenoterracide

I realize that I'd like the consumers of our API to not have to handle an exception. Or perhaps more clearly I'd like to ensure that the exception is always logged, but only the consumer will know how to handle success. I want the client to be able to handle the exception as well if they want, There is no valid Filethat I could return to them.

我意识到我希望 API 的使用者不必处理异常。或者更清楚的是,我想确保始终记录异常,但只有消费者知道如何处理成功。如果客户愿意,我希望客户也能够处理异常File,我无法返回给他们。

Note: FileDownloadis a Supplier<File>

注:FileDownload是一个Supplier<File>

@Override
public CompletableFuture<File> processDownload( final FileDownload fileDownload ) {
    Objects.requireNonNull( fileDownload );
    fileDownload.setDirectory( getTmpDirectoryPath() );
    CompletableFuture<File> future = CompletableFuture.supplyAsync( fileDownload, executorService );
    future... throwable -> {
        if ( throwable != null ) {
            logError( throwable );
        }
        ...
        return null; // client won't receive file.
    } );
    return future;

}

I don't really understand the CompletionStagestuff. Do I use exceptionor handle? do I return the original future or the future they return?

我真的不明白这些CompletionStage东西。我使用exceptionhandle? 我是返回原来的未来还是他们返回的未来?

回答by Jeffrey

Assuming that you do not want to affect the result of your CompletableFuture, you'll want to use CompletableFuture::whenComplete:

假设你不想影响你的结果CompletableFuture,你会想要使用CompletableFuture::whenComplete

future = future.whenComplete((t, ex) -> {
  if (ex != null) {
    logException(ex);
  }
});

Now when the consumer of your API tries to call future.get(), they will get an exception, but they don't necessarily need to do anything with it.

现在,当您的 API 的使用者尝试调用 时future.get(),他们会得到一个异常,但他们不一定需要对它做任何事情。



However, if you want to keep your consumer ignorant of the exception (return nullwhen the fileDownloadfails), you can use either CompletableFuture::handleor CompletableFuture::exceptionally:

但是,如果您想让您的消费者不知道异常(失败null时返回fileDownload),您可以使用CompletableFuture::handleCompletableFuture::exceptionally

future = future.handle((t, ex) -> {
  if (ex != null) {
    logException(ex);
    return null;
  } else {
    return t;
  }
});

or

或者

future = future.exceptionally(ex -> {
  logException(ex);
  return null;
});