Was ist der Unterschied zwischen Ausrufezeichen ( !) und Fragezeichen ( ?) beim Senden von Nachrichten an Schauspieler?
myActor ! Hello(value1)
myActor ? Hello(value1)
Antworten:
Schamlos kopiertes [fantastisches] offizielles Dokument (weitere Informationen finden Sie im Abschnitt Nachrichten senden ):
Nachrichten werden über eine der folgenden Methoden an einen Akteur gesendet.
!bedeutet "Feuer und Vergessen", z. B. asynchron eine Nachricht senden und sofort zurückkehren. Auch bekannt alstell.
?sendet eine Nachricht asynchron und gibtFutureeine mögliche Antwort zurück. Auch bekannt alsask.
Aus Sicht des Empfängers werden die Nachrichten auf dieselbe Weise angezeigt tellund askgesendet. Allerdings , wenn ein Empfang telldes Wertes senderwird der Schauspieler sein die Referenz, die die Nachricht gesendet, während für eine ask, die senderderart eingerichtet ist, dass jede Antwort auf die geht Futurein den Schauspieler geschaffen , die den geforderten tat.
Es hat den Vorteil ask, dass leicht zu erkennen ist, dass die Antwort, die Sie erhalten, definitiv auf die von Ihnen angeforderte Nachricht zurückzuführen ist, während Sie bei Tell möglicherweise eindeutige IDs verwenden müssen, um ein ähnliches Ergebnis zu erzielen. Jedoch mit askbenötigen Sie einen einstellen , timeoutnach der das Futurefehl , wenn keine Antwort empfangen wird.
Im folgenden Code wird der gleiche Effekt mit einem tellund und erzielt 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!"
}
}