我有以下代码将响应发送回发送方Actor(响应的actor使用Slick从表中加载列表):
class ManageUsersData extends Actor {
def receive = {
case _ => {
sender ! loadUsers
}
}
def loadUsers = {
var list = new ListBuffer[String]()
val db = Database.forConfig("dbconfig")
try {
val users: TableQuery[Users] = TableQuery[Users]
val future = db.run(users.result)
future onComplete {
case Success(u) => u.foreach {
user => {
list += user.firstName
}
list
}
case Failure(t) => println("An error has occured: " + t.getMessage)
}
} finally db.close
list
}
}
这里的问题是loadUsers
在等待Future完成之前返回。怎么能接近这个?
答案 0 :(得分:3)
您应该使用pipe pattern:
import akka.pattern.pipe
// ...
def receive = {
val originalSender = sender
loadUsers pipeTo originalSender
}
答案 1 :(得分:3)
Jean Logeart已经提到了概念解决方案。关于loadUsers,我认为这是一个较短的版本?
def loadUsers = {
val db = Database.forConfig("dbconfig")
try {
val users: TableQuery[Users] = TableQuery[Users]
db.run(users.result).map(_.firstName)
} catch {
case e: Exception => println("An error has occured: " + e.getMessage)
} finally db.close
}
答案 2 :(得分:2)
我认为,最简单的方法是将future
发送回sender
,而不是 async-filled list
。
在
中 def loadUsers = {
val db = Database.forConfig("dbconfig")
try {
val users: TableQuery[Users] = TableQuery[Users]
val future = db.run(users.result)
future.map { //the future
_.map { //the returning Seq
_.firstName
}
}
} finally db.close
}
现在调用者角色有处理未来或失败的负担。
这也有一个缺点,如果sender
使用ask
/ ?
操作,异步结果将是Future
包裹Future
pipeTo
}。
您可以使用sender
方法解决此问题,该方法会向调用方发送未来消息,而无需打扰解包它。
管道的缺点结果是firstName
应该有办法识别哪个回复属于哪个请求。一种可能的解决方案是发送一个请求标识符,该标识符将与答案一起发回,因此请求的演员可以轻松链接这两个。
为什么要在未来结果中映射 let dataManager = DataManager.getGolfCoursesFromFileWithSuccess { (data) -> Void in
let json = JSON(data: data)
if let courseArray = json.array {
for course in courseArray {
let golfCourseName: String? = course["biz_name"].string
let city: String? = course["e_city"].string
let state: String? = course["e_state"].string
if golfCourseName != nil {
let course = Course()
course.name = golfCourseName!
course.city = city!
course.state = state!
let realm = try! Realm()
try! realm.write {
realm.add(course)
}
}
}
}
}
属性而不是在光滑查询中使用投影?我认为这是为了保持示例的简单。