向演员发送消息时,感叹号(!
)和问号(?
)之间有什么区别?
myActor ! Hello(value1)
myActor ? Hello(value1)
答案 0 :(得分:110)
无耻地复制 [awesome] official doc(查看发送消息部分了解更多信息):
通过以下方法之一将消息发送给Actor。
!
表示“即发即忘”,例如异步发送消息 马上回来。也称为tell
。
?
发送消息 异步并返回表示可能回复的Future
。 也称为ask
。
答案 1 :(得分:19)
从收件人的角度来看,它会以同样的方式看到tell
和ask
条消息。但是,当收到tell
时,sender
的值将是发送邮件的参与者的引用,而对于ask
,sender
的设置为任何Future
回复转到执行询问的演员创建的ask
。
ask
有一个优势,很容易知道你收到的回复肯定是你问的消息的结果,而使用Tell,你可能需要使用唯一的ID来实现类似的结果。但是对于timeout
,您需要设置Future
,如果没有收到回复,tell
将会失败。
在下面的代码中,使用ask
和import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask
class TellActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
recipient ! "Hello" // equivalent to recipient.tell("hello", self)
case reply => println(reply)
}
}
class AskActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
implicit val timeout = 3 seconds
val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
replyF.onSuccess{
case reply => println(reply)
}
}
}
class ReceiveActor extends Actor {
def receive = {
case "Hello" => sender ! "And Hello to you!"
}
}
可以达到同样的效果。
verifyThat()