在番石榴中链接期货时处理异常

Handling exceptions when chaining Futures in guava

关于以下代码中的异常处理:

ListenableFuture<BufferedImage> imgFuture = downloadExecutor
                    .submit(new Downloader(url));
            ListenableFuture<BufferedImage> resizeFuture = Futures.transformAsync(
                    imgFuture, new AsyncFunction<BufferedImage, BufferedImage>()
                    {
                        @Override
                        public ListenableFuture<BufferedImage> apply(
                                BufferedImage input) throws Exception
                        {
                            ListenableFuture<BufferedImage> resizedFuture = null;
                            if (input != null)
                            {
                                resizedFuture = actionExecutor
                                        .submit(new ResizeImageAction(input));
                            }
                            return resizedFuture;
                        }
                    });

            ListenableFuture<BufferedImage> grayFuture = Futures
                    .transformAsync(resizeFuture, input -> {
                        return actionExecutor
                                .submit(new ToGrayImageAction(input));
                    });

假设提交给执行者的每个动作都会引发异常,这段代码将如何表现。

transformAsync() 方法是否知道不链接引发异常的空值或期货?使用 CheckedFuture 可以帮助我吗?如果可以,我该如何使用?

它知道抛出的异常,但不知道空值,因为它是完全合法的值。如果异常将在第一个 ListenableFuture 中抛出,那么它将传播到所有转换器:将调用它们的 onFailure 回调,但不会调用它们的转换(因为没有要转换的值)。

Javadoc 到 transformAsync:

@return A future that holds result of the function (if the input succeeded) or the original input's failure (if not)

简单示例:

ListenableFuture<Integer> nullFuture = executor.submit(() -> null);
ListenableFuture<Integer> exceptionFuture = executor.submit(() -> {
    throw new RuntimeException();
});

// Replace first argument with exceptionFuture to get another result
ListenableFuture<Integer> transformer = Futures.transformAsync(nullFuture, i -> {
    System.out.println(i);
    return Futures.immediateCheckedFuture(1);
}, executor);

Futures.addCallback(transformer, new FutureCallback<Integer>() {
    @Override
    public void onSuccess(Integer result) {
        System.out.println(result);
  }

    @Override
    public void onFailure(Throwable t) {
        System.out.println(t);
  }
});

对于 nullFuture "null and 1" 将被打印,而对于 exceptionFuture 将仅打印 "java.lang.RuntimeException",因为异常已传播到其转换器。