2013-04-02 5 views
18

traverseFuture से विधि पहली विफलता पर बंद हो जाती है। मैं इस विधि का सहिष्णु/क्षमा करने वाला संस्करण चाहता हूं जो त्रुटियों की घटना के अनुक्रम के साथ चलता है।विफलता के बावजूद भविष्य अनुक्रम निष्पादित करने के लिए कैसे?

वर्तमान में हम हमारे utils के लिए निम्न विधि जोड़ लिया है:

def traverseFilteringErrors[A, B <: AnyRef] 
          (seq: Seq[A]) 
          (f: A => Future[B]): Future[Seq[B]] = { 
    val sentinelValue = null.asInstanceOf[B] 
    val allResults = Future.traverse(seq) { x => 
    f(x) recover { case _ => sentinelValue } 
    } 
    val successfulResults = allResults map { result => 
    result.filterNot(_ == sentinelValue) 
    } 
    successfulResults 
} 

वहाँ यह करने के लिए एक बेहतर तरीका है?

उत्तर

21

वास्तव में उपयोगी चीज (आमतौर पर बोलने) एक भविष्य की त्रुटि को उचित मूल्य में बढ़ावा देने में सक्षम होगी। या दूसरे शब्दों में, Future[T] को Future[Try[T]] में बदलें (सफल वापसी मान Success[T] बन जाता है जबकि विफलता केस Failure[T] बन जाता है)। ,

Future.traverse(seq)(f andThen mapValue) 

आप एक सफल Future[Seq[Try[A]]], जिसका अंतिम मूल्य प्रत्येक सफल भविष्य के लिए एक Success उदाहरण शामिल प्राप्त करेंगे:,

// Can also be done more concisely (but less efficiently) as: 
// f.map(Success(_)).recover{ case t: Throwable => Failure(t) } 
// NOTE: you might also want to move this into an enrichment class 
def mapValue[T](f: Future[T]): Future[Try[T]] = { 
    val prom = Promise[Try[T]]() 
    f onComplete prom.success 
    prom.future 
} 

अब अगर आप निम्न करें: यहाँ हम यह कैसे लागू हो सकता है और प्रत्येक असफल भविष्य के लिए Failure उदाहरण। यदि आवश्यक हो, तो आप Failure उदाहरणों को छोड़ने के लिए collect का उपयोग इस सीक पर कर सकते हैं और केवल सशक्त मान रख सकते हैं।

def traverseFilteringErrors[A, B](seq: Seq[A])(f: A => Future[B]): Future[Seq[B]] = { 
    Future.traverse(seq)(f andThen mapValue) map (_ collect{ case Success(x) => x }) 
} 
+2

कूल:

दूसरे शब्दों में, आप निम्नानुसार अपने सहायक विधि पुनर्लेखन कर सकते हैं। क्या आप टिप्पणी कर सकते हैं कि वैकल्पिक विकल्प ('f.map (सफलता ... ') कम कुशल है? – sourcedelica

+3

क्योंकि' मानचित्र 'के साथ-साथ' पुनर्प्राप्ति '' वादा' के उदाहरण बनाते हैं और उनके संबंधित 'भविष्य' को वापस करते हैं। यह दो है मेरे वैकल्पिक समाधान के लिए केवल एक के बजाय 'वादा' की प्रशंसाएं। साथ ही, "संक्षिप्त" संस्करण 'प्रयास' उदाहरण को अनदेखा करता है (जिसे 'वादा' उदाहरणों के अंदर संग्रहीत किया जाता है) केवल इसे 'सफलता' या 'विफलता' के रूप में अनावश्यक रूप से पुनर्विचार करने के लिए 'उदाहरण, जो कि अपमानजनक है। बेशक, आपको यह देखने के लिए प्रोफाइल करना होगा कि क्या यह वास्तव में इस तरह का सार्थक अंतर बनाता है। –

+0

धन्यवाद! यह वास्तव में सहायक है। – sourcedelica

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

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