2013-02-24 83 views
10

मैं उपयोग कर रहा हूँ:स्केला, नाटक, वायदा: कई वायदा से संयोजन परिणाम

  • स्काला 2.10
  • प्ले 2,1

वर्तमान में, मैं scala.concurrent._ से Future वर्ग का उपयोग कर रहा है, लेकिन मैं मैं एक और एपीआई कोशिश करने के लिए खुला हूँ।

मुझे एक सूची में कई वायदा के परिणामों को जोड़ने में परेशानी हो रही है [(स्ट्रिंग, स्ट्रिंग)]।

निम्नलिखित Controller विधि सफलतापूर्वक एक HTML टेम्पलेट के लिए एक एकल भविष्य के परिणाम देता है:

def test = Action { implicit request => 
    queryForm.bindFromRequest.fold(
     formWithErrors => Ok("Error!"), 
     query => { 
     Async { 
      getSearchResponse(query, 0).map { response => 
      Ok(views.html.form(queryForm, 
       getAuthors(response.body, List[(String, String)]()))) 
      } 
     } 
     }) 
    } 

विधि getSearchResult(String, Int) एक वेब सेवा API कॉल करता है और देता है एक भविष्य [play.api.libs.ws .Response]। विधि getAuthors(String, List[(String, String)]) HTML टेम्पलेट में एक सूची [(स्ट्रिंग, स्ट्रिंग)] देता है।

अब, मैं getSearchResult(String, Int) को for लूप में कई प्रतिक्रिया निकायों को प्राप्त करने की कोशिश कर रहा हूं। मुझे क्या करना है कोशिश कर रहा हूँ की एक विचार देना चाहिए निम्नलिखित है, लेकिन मैं एक संकलन समय त्रुटि मिलती है:

def test = Action { implicit request => 
    queryForm.bindFromRequest.fold(
     formWithErrors => Ok("Error!"), 
     query => { 
     Async { 
      val authors = for (i <- 0 to 100; if i % 10 == 0) yield { 
      getSearchResponse(query, i) 
      }.map { response => 
      getAuthors(response.body, List[(String, String)]()) 
      } 

      Ok(views.html.form(queryForm, authors)) 
     } 
     }) 
    } 

प्रकार मेल नहीं खाता; पाया: scala.collection.immutable.IndexedSeq [scala.concurrent.Future [सूची [(स्ट्रिंग, स्ट्रिंग)]]] की आवश्यकता: सूची [(स्ट्रिंग, स्ट्रिंग)]

मैं कैसे कई की प्रतिक्रियाओं मैप कर सकते हैं Future ऑब्जेक्ट्स को एक Result पर ऑब्जेक्ट्स?

उत्तर

9

किसी सूची या परिणाम प्रकार के अन्य संग्रह द्वारा भविष्य में पैरामीट्रिज्ड बनाएं।

here से:

प्ले 1 में आप यह कर सकते हैं:

F.Promise<List<WS.HttpResponse>> promises = F.Promise.waitAll(remoteCall1, remoteCall2, remoteCall3); 

    // where remoteCall1..3 are promises 

    List<WS.HttpResponse> httpResponses = await(promises); // request gets suspended here 

प्ले 2 कम प्रत्यक्ष में:

val httpResponses = for { 
    result1 <- remoteCall1 
    result2 <- remoteCall2 
} yield List(result1, result2) 
+0

हम्म, उस लिंक मदद करता है। मैंने जूलियन रिचर्ड-फोय द्वारा पोस्ट किए गए दृष्टिकोण की कोशिश की: 'वैल httpResponses = Promise.sequence (सूची (रिमोटकॉल 1, रिमोटकॉल 2))। इसने मुझे 'भविष्य [इंडेक्सेडसेक [प्रतिक्रिया]]' का उदाहरण प्राप्त करने की अनुमति दी है, जो कि कमाल है। हालांकि, मैं अभी भी प्रतिक्रियाओं की सूची को [[स्ट्रिंग, स्ट्रिंग) की एक सूची में मैप करने की कोशिश कर रहा हूं]। अभी, यह केवल पहले भविष्य –

+0

@DavidKaczynski के परिणाम को मैप कर रहा है, मेरे जावा ऐप में हमने एक छोटी वादा लाइब्रेरी लिखने को घायल कर दिया और 'वादा किया। जब सभी (वादा ...)' विधि बनाई। तो आपके प्रश्न पर शोध करने में मैंने सामान के लिए गुगलिंग की कोशिश की, "संग्रह से स्काला प्ले वादा," "... सूची से," आदि। इस तरह की एक विधि मैं वास्तव में बहुत मानक होने की उम्मीद करता हूं। यह भी देखें: https://github.com/playframework/Play20/pull/677 – djechlin

+0

आगे निरीक्षण पर, मेरी पहली टिप्पणी में वर्णित विधि ने काम किया। मेरे पास एक और "बग" था जो केवल एक भविष्य से परिणाम लौट रहा था। एक बार जब मैंने ** अलग ** फ्यूचर्स के अनुक्रम से वादा किया, तो मुझे एक ही भविष्य में सभी प्रतिक्रियाएं मिल रही थीं। अद्भुत सामान! –