2013-04-05 9 views
13

मुझे पता है कि मेरी समस्या थोड़ा जटिल लग सकती है। लेकिन मैं खुद को अच्छी तरह व्यक्त करने की कोशिश करूंगा।स्केल में एसिंक्रोनस कार्यों को पूरा करने के लिए मैं कैसे प्रतीक्षा करूं?

मेरे पास यह तरीका है जिसे मैं Map[String, List[String]] डेटा से भरना चाहता हूं।

def myFunction():Map[String, List[String]] = { 

    val userMap = Map[String, String](("123456", "ASDBYYBAYGS456789"), 
            ("54321", "HGFDSA5432")) 

    //the result map to return when all data is collected and added 
    val resultMap:Future[Map[String, List[String]]] 

    //when this map is finished (filled) this map is set to resultMap 
    val progressMap = Map[String, List[String]]() 

    for(user <- userMap){ 

    //facebook graph API call to get posts. 
    val responsePost = WS.url("async get to facebook url").get() 

    responsePosts.flatMap { response => 
     val jsonBody = response.json 
     val dataList = List[String]() 

     for(i <-0 until 5){ 

      //parse the json-data to strings 
      val messages = (jsonBody.\("statuses").\("data")(i).\("message")) 
      val likesArray = (jsonBody.\("statuses").\("data")(i).\\("data")).flatMap(_.as[List[JsObject]]) 
      val likes = likesArray.length 

      //Put post with likes in temporary list 
      dataList ::=  ("Post: " + message.toString + " Likes: " + likes.toString) 
     } 

      //facebook graph API call to get friends. 
      val responseFriends = WS.url("async get to facebook url").get() 

      responseFriends.map { response => 
       val jsonBody = response.json 
       val friendCount = jsonBody.\("data")(0).\("friend_count").toString 

       //add "Friends: xxx" to the dataList and add the new row to resultMap containig a list with post and friends. 
       dataList ::= ("Friends: " + friendCount) 
       progressMap += user._1 -> dataList 

       //check if all users has been updated 
       if(progressMap.size == userMap.size){ 
        resultMap = progressMap 
       } 
      } 
     } 
    } 

    //return the resultMap. 
    return resultMap 
} 
} 

मेरा कोड इष्टतम वाक्यविन्यास के साथ नहीं लिखा जा सकता है।

लेकिन मैं जो चाहता हूं वह डेटा के साथ इस परिणाम मैप को वापस करना है। मेरी समस्या यह है कि "get to facebook url" असीमित रूप से किया जाता है क्योंकि यह परिणाम मैप खाली हो जाता है। मैं नहीं चाहता कि यह खाली हो।

मेरी विधि में यह कोड अब तक मेरा समाधान है। यह स्पष्ट रूप से काम नहीं करता है, लेकिन मुझे उम्मीद है कि आप देख सकते हैं कि मैं क्या करने की कोशिश कर रहा हूं। अपने विचारों के उत्तर देने के लिए स्वतंत्र महसूस करें, भले ही आप सुनिश्चित न हों, यह मुझे सही रास्ते पर रख सकता है।

+0

डेटा के मूल्यों को आप कैसे जोड़ सकते हैं यदि यह एक वैल है? –

उत्तर

25

उपयोग scala.concurrent.{Future, Promise}:

def doAsyncAction: Promise[T] = { 
    val p = Promise[T] 
    p success doSomeOperation 
    p 
} 

def useResult = { 
    val async = doAsyncAction; 
    // The return of the below is Unit. 
    async.future onSuccess { 
     // do action. 
    }; 
}; 

एक और तरीका है Await परिणाम है। (यह एक अवरुद्ध कार्रवाई है)।

प्रयुक्त जब आप परिणाम

import scala.concurrent.{ ExecutionContext, ExecutionContext$, Future, Promise, Await } 
import scala.concurrent.duration._ 

def method: Option[T] = { 
    val future: Future[T] = Future { 
     someAction 
    } 
    val response = future map { 
     items => Some(items) 
    } recover { 
     case timeout: java.util.concurrent.TimeoutException => None 
    } 
    Await.result(future, 5000 millis); 
}; 

अपने स्वयं के निष्पादक में वायदा अवरुद्ध निष्पादित करने के लिए सावधान रहें वापस जाने के लिए की जरूरत है, अन्यथा आप अन्य समानांतर गणना अवरुद्ध अंत। यह विशेष रूप से एस 2 एस और आरपीसी अनुरोधों के लिए उपयोगी है, जहां अवरोध कभी-कभी अनदेखा होता है।

+0

आपके उत्तर के लिए धन्यवाद, इससे मदद मिली :) हालांकि मेरा समाधान जो इसे काम करने के लिए मिला था, वह 'वादा [मानचित्र [स्ट्रिंग, सूची [स्ट्रिंग]]]' का उपयोग करना था और जब मैंने इसे बुलाया तो मैंने वादे के भविष्य की जांच की। और उस भविष्य पर असफल होने पर, मैंने कुछ किया। शायद मुझे अपना समाधान पोस्ट करना चाहिए। यदि ऐसा है तो मुझे बताएं। – raxelsson

+4

कृपया अपना समाधान पोस्ट करें, मुझे दिलचस्पी है –

+0

@flavian धन्यवाद –

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

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