我如何等待异步任务在斯卡拉完成? [英] How do I wait for asynchronous tasks to complete in scala?
问题描述
我知道,我的问题似乎有点复杂。但我会尽力的前preSS自己好。
I'm aware that my problem might seem a little bit complex. But I'll try to express myself well.
我有这种方法,我想返回一个地图[字符串,列表[字符串]]
填充数据。
I have this method which I want to return a Map[String, List[String]]
filled with data.
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
}
}
我的code可能无法以最佳语法来写。
My code might not be written with optimal syntax.
但我想要的是返回此结果映射数据。
我的问题是:由于去Facebook网址
是异步完成这个结果映射返回空。我不希望这是空ofcourse。
But what I want is to return this resultMap with data.
My problem is that since the "get to facebook url"
is done asynchronously this resultMap is returned empty. I do not want this to be empty ofcourse.
在我的方法这code是我的解决方案为止。它不工作,很明显,但我希望你能看到我想要做的。随时与你的想法来回答,即使你不确定,它可能把我在正确的轨道上。
This code in my method is my solution so far. It does not work, obviously, but I hope you can see what I'm trying to do. Feel free to answer with your thoughts even though youre not sure, it might put me on the right track.
推荐答案
使用 scala.concurrent {未来,无极}
:
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.
};
};
另一种方法是等待
的结果。 (这是一个阻塞动作)。
Another way is to Await
the result. (this is a blocking action).
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请求,发生阻塞有时取消可以避免尤其有用。
Be careful to execute blocking Futures in their own executor, otherwise you end up blocking other parallel computation. This is especially useful for S2S and RPC requests, where blocking is sometimes un-avoidable.
这篇关于我如何等待异步任务在斯卡拉完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!