如何等待异步任务在scala中完成?
我知道我的问题看起来有点复杂。但我会尽力表达自己。如何等待异步任务在scala中完成?
我有这种方法,我想返回一个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
}
}
我的代码可能不会写入最佳语法。
但我想要的是返回此resultMap与数据。 我的问题是,因为"get to facebook url"
是异步完成的,所以resultMap返回为空。我不希望这是空的。
我的方法中的这段代码是我迄今为止的解决方案。这显然不起作用,但我希望你能看到我想要做的事情。即使你不确定,也可以随意回答你的想法,这可能会让我走上正轨。
使用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);
};
小心执行在自己的遗嘱执行人阻塞期货,否则你最终会阻塞其它并行计算。这对于S2S和RPC请求尤其有用,其中阻塞有时是不可避免的。
谢谢你的回答它帮助:)虽然我的解决方案得到它的工作是使用返回一个'Promise [Map [String,List [String]]]'当我打电话时,我检查了承诺的未来。在未来的成功之路上,我做了一些事情。也许我应该发布我的解决方案。如果是的话,让我知道。 – raxelsson 2013-04-08 07:49:37
请发布您的解决方案,我感兴趣 – 2013-08-12 16:58:54
@flavian谢谢 – 2013-08-12 20:10:36
如何将值追加到dataList如果它是一个VAL? – 2013-08-12 18:10:56