наконец, эквивалент блока для обработки исключений в CompletableFuture - PullRequest
0 голосов
/ 26 января 2019

У меня есть CompletableFuture, который может вернуть результат или исключение.Я хочу выполнить какой-то общий код в случае исключения и нормального результата.Похоже на try catch finally block

Текущая реализация

CompletableFuture<Integer> future= CompletableFuture.supplyAsync(this::findAccountNumber)
                             .thenApply(this::calculateBalance)                      
                             .thenApply(this::notifyBalance)
                             .exceptionally(ex -> {
                                 //My Exception Handling logic 
                                 return 0;
                             });

Где я могу поставить свою логику finally?

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Ближайший эквивалент finally равен whenComplete.Как и handle, он принимает функцию, получающую либо значение результата, либо бросаемое значение, но он не предоставляет значение результата замещения, а новый этап завершения не изменит результат, как finally.

So

static int decode(String s) {
    try {
        return Integer.parseInt(s);
    }
    finally {
        System.out.println("finally action");
    }
}

эквивалентно

static int decode1(String s) {
    return CompletableFuture.completedFuture(s)
        .thenApply(Integer::parseInt)
        .whenComplete((i,t) -> System.out.println("finally action"))
        .join();
}

Так что при использовании с

for(String s: Arrays.asList("1234", "foo bar")) try {
    System.out.println("decoded: "+decode(s));
} catch(Exception ex) {
    System.out.println("decoding "+s+" failed with "+ex);
}

первый вариант печатает

finally action
decoded: 1234
finally action
decoding foo bar failed with java.lang.NumberFormatException: For input string: "foo bar"

и последний печатает

finally action
decoded: 1234
finally action
decoding foo bar failed with java.util.concurrent.CompletionException: java.lang.NumberFormatException: For input string: "foo bar"

Общим для обоих является то, что исключение, сгенерированное в действии finally, заменит исходный результат, затеняя исключение, если блок try / предыдущий этап завершен исключительно.

0 голосов
/ 26 января 2019

handle() Метод обеспечивает более гибкий подход. она принимает функцию, получающую либо правильный результат, либо исключение:

Из документа Java

handle(BiFunction<? super T,Throwable,? extends U> fn)

Возвращает новый CompletionStage, который по завершении этого этапа либо обычно или исключительно, выполняется с результатом этого этапа и исключение в качестве аргументов для предоставленной функции.

CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(this::findAccountNumber)
                         .thenApply(this::calculateBalance)                      
                         .thenApply(this::notifyBalance)        
                         .handle((ok, ex) -> {
                            System.out.println("Code That we want to run in finally ");
                            if (ok != null) {
                                    System.out.println("No Exception !!");
                            } else {

                                System.out.println("Got Exception " + ex.getMessage());
                                return -1;
                            }
                            return ok;
                        });
...