2015-07-10 20 views
8

arasındaki etkileşim:Fonksiyonel Java - Bu kodda whenComplete ve son derece

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

doSomethingThatMightThrowAnException bir istisna vardır, hem doSomethingElse ve handleException koşmak, ya da istisna whenComplete veya exceptionally biri tarafından tüketilmektedir?

DÜZENLEME:

doSomethingThatMightThrowAnException hangi completeExceptionally belki bir CompletableFuture döndürür. Bu bahsettiğim istisna.

cevap

10

documentation of whenComplete diyor ki:

bu aşamada tamamlandığında verilen eylemi çalıştırır bu aşamada, aynı sonucu ya haricinde yeni CompletionStage döndürür.

(vurgu benim)

aynı sonucu veya istisna olması gerekiyordu bir istisna bu aşamada tarafından yutulur olmadığını ima eder.Ancak, here tartışıldığı gibi sonradan aşamaları, bir CompletionException içinde sarılı bir önceki aşamanın istisna alacaksınız gerçeğiyle sürpriz olabilir, bu yüzden tam olarak aynı istisna değil:

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()); 

yazdırır:

her zaman sonra zincirleme yerine bir sahnede birden çok eylem ekleyebilirsiniz
stage 2: null java.io.IOException 
stage 3: java.util.concurrent.CompletionException: java.io.IOException 

Not:

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()); 

Tabii ki şu andan itibaren, 2a ve 2b aşamaları arasında hiçbir bağımlılık yoktur, bunlar arasında bir sıra yoktur ve eşzamanlı olmayan bir eylem durumunda eşzamanlı olarak çalışabilirler.

0

doSomethingThatMightThrowAnException(), .whenComplete ((sonuç, ex) -> doSomethingElse()}) ve .exceptionally (ex -> handleException (ex)) ile zincirlenmiştir; ancak bir istisna atarsa, zincirde hiçbir nesne geçmeyeceği için burada bitecektir.

Bir istisnanın arayan kişiye atılacağını unutmayın, bu nedenle doSomethingThatMightThrowAnException() öğesi, istisnai olarak dahili olarak yakalanmadıkça atılacaktır. Eğer sınıfınız bu ise, attığınızı bilmeniz gerekiyor, eğer kullandığınız lilbraris için dokümanlar kontrol edilmiyorsa.

1

exceptionally yöntem devletler:

bu CompletableFuture o derece tamamlandığında bu CompletableFuture en tamamlanmasını tetikleme istisna verilen fonksiyonun sonucu, tamamlandığında tamamlanır yeni CompletableFuture döndürür; Aksi takdirde, bu CompletableFuture normal olarak tamamlanırsa, döndürülmüş CompletableFuture da normalde aynı değerle tamamlar. Not: Bu işlevin daha esnek sürümleri, Tamamlanma ve işleme yöntemleri kullanılarak kullanılabilir.

Bu IMHO en net ingilizce yazılı değil ama bu bir istisna atılır eğer sadece exceptionally işlem tetiklenir olacağı anlamına gelir söyleyebilirim. Hiçbir istisna atılmazsa, sadece normal eylemi gerçekleştirilecektir.

İlgili konular