我试图在将来改变FSM状态,但我没有工作...... 我想我正在寻找pipeTo like method。
When(State.Waiting) {
case Event(anyMsg, anyData) =>
asyncCode.map(res =>
if (res == 1) {
goto(State.Working) using Data.MyData
} else {
stay() replying "bad response"
}
)
}
goto命令执行但fsm没有将状态更改为State.Working
我自己找到了这个工作
When(State.Waiting) {
case Event(anyMsg, anyData) =>
asyncCode.map(res =>
if (res == 1) {
self ! "do job"
} else {
stay() replying "bad response"
}
)
case Event("do job", anyData) => {
goto(State.Working) using Data.MyData
}
}
可能有更好的解决问题的想法
答案 0 :(得分:8)
不要在将来改变你的演员的状态,也不要改变主"线程"内的任何东西。 解决问题的正确方法是向self发送一条消息,这将改变状态,如
When(State.Waiting) {
case Event(anyMsg, anyData) =>
asyncCode.map(res =>
if (res == 1) {
self ! GoToWorking(Data.MyData)
} else {
self ! Stay
}
)
goto(State.WaitingForResponse)
}
When (State.WaitingForResponse) {
case Event(GoToWorking(data), _) =>
goto(State.Working) using data
case Event(Stay,_) =>
stay()
}
答案 1 :(得分:5)
您永远不应该从异步回调中关闭并修改actor的状态(例如Future组合器)。对于FSM方法也是如此,它们对于actor是私有的。 actor应该对异步事件做出反应的唯一方法是接收消息。你的第二个代码几乎是正确的,除了你甚至不应该从回调中调用stay()。异步结果应该最终作为发送给actor的消息,然后可以改变它的状态。您可能希望引入一个新的等待状态,在启动异步调用时转换到该状态,一旦完成(actor接收结果),请转到State.Working。