Funzionale Java – Interazione tra whenComplete ed eccezionalmente

In questo codice:

doSomethingThatMightThrowAnException()
  .whenComplete((result, ex) -> doSomethingElse()})
  .exceptionally(ex -> handleException(ex));

Quando c’è un’eccezione da doSomethingThatMightThrowAnException, sono entrambi doSomethingElse e handleException eseguire, o è l’eccezione consumato dal whenComplete o il exceptionally?

EDIT:

doSomethingThatMightThrowAnException restituisce un CompletableFuture, che potrebbe completeExceptionally. Questa è l’eccezione di cui sto parlando.

InformationsquelleAutor peco | 2015-07-10

 

3 Replies
  1. 18

    Il la documentazione di whenComplete dice:

    Restituisce un nuovo CompletionStage con lo stesso risultato o eccezione in questa fase, che esegue l’azione determinata quando questa fase di completa.

    (corsivo mio)

    Questo implica che un’eccezione non viene inghiottito da questa fase in quanto si suppone di avere lo stesso risultato o eccezione. Tuttavia, si potrebbe essere sorpresi dal fatto che le successive fasi di ricevere l’eccezione di una fase precedente avvolto all’interno di un CompletionException, come discusso qui, quindi non è esattamente la stessa eccezione:

    CompletableFuture<String> test=new CompletableFuture<>();
    test.whenComplete((result, ex) -> System.out.println("stage 2: "+result+"\t"+ex))
        .exceptionally(ex -> { System.out.println("stage 3: "+ex); return ""; });
    test.completeExceptionally(new IOException());

    stampa:

    stage 2: null   java.io.IOException
    stage 3: java.util.concurrent.CompletionException: java.io.IOException

    Si noti che è sempre possibile aggiungere più azioni su un palco invece di concatenamento quindi:

    CompletableFuture<String> test=new CompletableFuture<>();
    test.whenComplete((result, ex) -> System.out.println("stage 2a: "+result+"\t"+ex));
    test.exceptionally(ex -> { System.out.println("stage 2b: "+ex); return ""; });
    test.completeExceptionally(new IOException());
    stage 2b: java.io.IOException
    stage 2a: null  java.io.IOException

    Ovviamente, visto che ora non c’è dipendenza tra la fase 2a e 2b, non c’è nessun ordinamento tra di loro e, nel caso di azione asincrona, possono essere eseguiti contemporaneamente.

  2. 2

    Il eccezionalmente metodo uniti:

    Restituisce un nuovo CompletableFuture che è completata quando questo CompletableFuture completa, con il risultato di una data funzione di eccezione per l’attivazione di questo CompletableFuture di completamento, quando è completa di eccezionale; in caso contrario, se questo CompletableFuture completa normalmente, poi restituito CompletableFuture completa normalmente con lo stesso valore. Nota: Più flessibile versioni di questa funzionalità sono disponibili utilizzando metodi whenComplete e maniglia.

    Questo non è, IMHO scritto nella maniera più chiara e inglese, ma direi che significa che se viene generata un’eccezione solo il exceptionally azione verrà attivato. Se non viene generata alcuna eccezione solo il normal verrà eseguita l’azione.

  3. 0

    doSomethingThatMightThrowAnException() è incatenato con .whenComplete((result, ex) -> doSomethingElse()}) e .exceptionally(ex -> handleException(ex)); ma se viene generata un’eccezione non finisce proprio lì, come nessun oggetto sarà trasmesso in catena.

    Ricordare che l’eccezione di buttare fuori al chiamante, quindi a meno che non doSomethingThatMightThrowAnException() intercetta l’eccezione internamente sarà buttare fuori. Se questa è la tua classe, è necessario sapere se fa buttare, se non controllare documenti per le biblioteche che si utilizza.

Lascia un commento