我在播放框架中使用了json4s,并且我将来会在某些地方运行发布/获取请求,然后onSuccess将响应解析为一个对象并让演员将其发回对自己来说..这是一个例子:
WS.url(authUrl).post("username=admin&password=admin") map {
response =>
self ! (parse(response.body) \ "body").extract[AuthObject]
}
然后返回接收方法:
case AuthObject(_, sid) => //handle authorization token
这是不好的做法吗?有什么正确的方法可以解决这个问题?我看到的优势是能够让你的演员数据流由单一的控制结构处理,但当然我说这是一个优势是错误的。
答案 0 :(得分:8)
向演员发送未来结果的recommended方法是使用pipe
模式。您的代码将如下所示:
def receive:Reveice= {
case authUrl:String =>
val authObjectF=WS.url(authUrl).post("username=admin&password=admin") map { response =>
(parse(response.body) \ "body").extract[AuthObject]
}
authObjectF pipeTo self
}
这被认为优于map {x => self ! x }
的原因是错误处理。如果您不处理错误情况,它们将被默默地丢弃。
使用pipe
模式,错误将包含在akka.actor.Status.Failure
中并发送到目标参与者(在本例中为self
),而不是结果。
将未来的结果管道化为self是一种常见的模式,可能与context.become / unbecome和stash一起使用以创建状态机。
在map / flatmap中关闭actor内部可变状态并且在执行此操作时打破actor模型的并发保证仍然非常容易。如果你在演员中操纵未来我强烈建议你阅读这个http://doc.akka.io/docs/akka/2.3.2/general/jmm.html#jmm-shared-state,如果你还没有这样做的话。
答案 1 :(得分:1)
它没有任何内在错误。向自己发送消息类似于人类保持"做"列出并将一些内容放在列表的末尾。你的演员最终会到达那里。并且,这确实是唯一的问题:何时处理AuthObject
消息的时间。如果您的应用程序只需要订购但不需要时间保证,那么可以这样处理它。
但是,我会警惕你的\运算符在没有" body"的情况下返回JsError。你的response.body中的字段(大概是Json)。在这种情况下,您的消息永远不会被发送,并且在任何地方都没有发送任何错误。