2015-02-21 11 views
6

मुझे असीमित परिणाम के साथ अपवाद को संभालने का एक स्पष्ट तरीका दिखाई नहीं देता है। उदाहरण के लिए, अगर मैं एक एसिंक ऑपरेशन पुनः प्रयास करना चाहता हूं। मैं इस तरह कुछ की उम्मीद करता हूं, हालांकि हैंडलएसिंक ऐसा नहीं करता जो आपको लगता है - यह कॉलबैक को अन्य थ्रेड पर असीमित रूप से चलाता है। यहां एक ComplestStage वापस लौटना सही नहीं है। दिन के खतरे का सवाल: तब अपवाद के रूप में अपवाद है तो क्या करना है।जावा 8 CompletableFuture पुनर्प्राप्ति के बराबर के साथ? उदाहरण के लिए असाधारण रूप से लेकिन CompletableFuture <U>

CompletionStage<String> cf = askPong("cause error").handleAsync((x, t) -> { 
     if (t != null) { 
      return askPong("Ping"); 
     } else { 
      return x; 
     } 
    }); 

कहाँ askPong एक अभिनेता पूछते हैं:

public CompletionStage<String> askPong(String message){ 
    Future sFuture = ask(actorRef, message, 1000); 
    final CompletionStage<String> cs = toJava(sFuture); 
    return cs; 
} 
+0

"सही नहीं है" का क्या अर्थ है? आप किस व्यवहार की तलाश में हैं? –

+0

वह संकलित नहीं होगा। आप में एक CompletableFuture वापस नहीं कर सकते हैं हैंडलएसिंक - आपको यू को वापस करना होगा। मैं अपवाद मामले में के बजाय एक CompletableFuture वापस करने में सक्षम होना चाहता हूं। मैं स्केल के बराबर की तलाश कर रहा हूं या वादा वसूली खेल सकता हूं (जो असाधारण रूप से है लेकिन फ़ंक्शन में असीमित परिणाम के साथ)। – JasonG

+0

मैंने प्रश्न में थोड़ा सा स्पष्ट करने की कोशिश की। हो सकता है कि मैं हैंडलएसिंक का सही उपयोग नहीं कर रहा हूं लेकिन इसका मतलब यह नहीं है "और एक एसिंक परिणाम लौटाएं"। – JasonG

उत्तर

10

यह आपके लिए क्या देख रहे है?

askPong("cause error") 
     .handle((pong, ex) -> ex == null 
       ? CompletableFuture.completedFuture(pong) 
       : askPong("Ping") 
     ).thenCompose(x -> x); 

इसके अलावा, ...Async विधियों का उपयोग नहीं जब तक आप की आपूर्ति समारोह के शरीर के लिए इरादा एसिंक्रोनस रूप से निष्पादित किया जाना है। तो जब आप की तरह

.handleAsync((x, t) -> { 
    if (t != null) { 
     return askPong("Ping"); 
    } else { 
     return x; 
    }) 

कुछ करना आप if-then-else के लिए पूछ रहे हैं एक अलग थ्रेड में चलाने के लिए। चूंकि askPongCompletableFuture देता है, इसलिए संभवतः इसे असीमित रूप से चलाने का कोई कारण नहीं है।

+3

यह भयानक है। लेकिन यह काम करता है। हालांकि समाधान के लिए धन्यवाद! उस बारे में सोचा नहीं था। हालांकि यह एक हैक है - एपीआई में असाधारण रूप से कॉम्पोज़ विधि होनी चाहिए। – JasonG

+0

निराशाजनक तरह की तरह नहीं है! मैं https://github.com/javaslang/javaslang का उपयोग कर समाप्त कर सकता हूं जो एक बेहतर भविष्य इंटरफ़ेस – Setheron

1

स्कैला की वसूली करने के उचित तरीके को जानने का प्रयास करने में बहुत निराशा के बाद जावा 8 में, मैंने अपना खुद का लेखन समाप्त कर दिया। मैं अब भी अगर यह सबसे अच्छा तरीका है पता नहीं है, लेकिन मुझे लगता है जैसे कुछ बनाया:

public RecoveryChainAsync<T> recoverWith(Function<Throwable, 
             CompletableFuture<T>> fn); 

recoverWith के लिए कई बार कॉल के साथ, मैं वसूली श्रृंखला के अंदर कार्यों को कतार और वसूली के साथ अपने आप को प्रवाह को लागू "संभाल "। RecoveryChainAsync.getCompletableFuture() फिर पूरी श्रृंखला के लिए एक प्रतिनिधि CompletableFuture देता है। उम्मीद है की यह मदद करेगा।

+1

Java8 lib में सामान का एक समूह गुम है। मैं बेहतर जावा-मोनैड्स नामक लाइब्रेरी पर काम कर रहा हूं - यदि आप पीआर बनाते हैं तो मैं आपके समाधान की समीक्षा कर सकता हूं। एक उपयोगी जोड़ हो सकता है। मैंने वायदा के लिए भी एक ट्रैवर्स जोड़ा। https://github.com/jasongoodwin/better-java-monads – JasonG

संबंधित मुद्दे