В чем разница между восклицательным знаком (!
) и вопросительным знаком (?
) при отправке сообщений Актерам?
myActor ! new hello(value1)
myActor ? new hello(value1)
В чем разница между восклицательным знаком (!
) и вопросительным знаком (?
) при отправке сообщений Актерам?
myActor ! new hello(value1)
myActor ? new hello(value1)
Бесстыдно скопировано [awesome] официальный документ (посмотрите еще Отправить сообщения):
Сообщения отправляются актеру одним из следующих способов.
!
означает "огонь и забыть", например. отправить сообщение асинхронно и немедленно возвращайтесь. Также известен какtell
.
?
отправляет сообщение асинхронно и возвращает aFuture
, представляющий возможный ответ. Также известен какask
.
С точки зрения получателя он видит сообщения tell
и ask
одинаково. Однако при приеме tell
значение sender
будет ссылкой для актера, который отправил сообщение, тогда как для ask
, sender
настроен таким образом, что любой ответ отправляется в созданный Future
в актере, который сделал запрос.
В ask
есть преимущество, что легко понять, что ответ, который вы получаете, определенно является результатом сообщения, которое вы задавали, тогда как с помощью Tell вам может потребоваться использовать уникальные идентификаторы для достижения аналогичного результат. Однако с ask
вам нужно установить 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!"
}
}