2017-03-23 3 views
1

は、実際のエージェントを使用する場合GenServerの親プロセスはどのように応答を待ちますか?

a = AAgent.start_agent 
send a, {:put, :a, 42, self()} 
flush 
%{a: 42} 

しかし、応答が呼び出し元プロセスのメールボックスに渡され、使われている公式のエリクサーガイド

defmodule AAgent do 
    def start_agent do 
    spawn_link fn -> loop(%{}) end 
    end 

    def loop(state \\ %{}) do 
    receive do 
     {:put, key, value, caller} -> 
     new_state = Map.put(state, key, value) 
     send caller, new_state 
     loop(new_state) 
     {:get, key, caller} -> 
     send caller, Map.get(state, key) 
     loop(state) 
    end 
    end 
end 

からのエージェントのような実装があります(内部GenServerを使用しています)、応答が

すぐに親プロセスに利用可能である
iex> Agent.get(agent, fn list -> list end) 
["eggs"] 

私は、NEはありません私がエージェントを使用すると["eggs"]を得るためにreceiveブロックを書きました。これは、別のプロセスにデータを渡した別のプロセスであっても、すでに利用可能な結果です。裸のプロセスを使用して同じ効果を達成することは可能ですか?GenServerはフードの下で何か他のものを使用していますか?

答えて

4

私はあなたが受け取る書きませんでしたが、Agent.getは、間接的にやるん

結果はすでに利用可能、私はエージェントを使用する場合、[「卵」]を取得するために受信ブロックを記述する必要はありませんa receive を呼び出して:gen.callwhich contains the receiveを呼び出してください。

defmodule AAgent do 
    def start_agent do 
    spawn_link fn -> loop(%{}) end 
    end 

    def loop(state \\ %{}) do 
    receive do 
     {:put, key, value, _caller} -> 
     new_state = Map.put(state, key, value) 
     loop(new_state) 
     {:get, key, caller} -> 
     send caller, Map.get(state, key) 
     loop(state) 
    end 
    end 

    def get(agent, key) do 
    send(agent, {:get, key, self()}) 
    receive do x -> x end 
    end 
end 

a = AAgent.start_agent 
send a, {:put, :a, 42, self()} 
IO.inspect AAgent.get(a, :a) 

出力:

42 
あなたは、コードのわずか4行を使用して、エージェントのための同じを実装することができます
4

受信ブロックはAgent.get/2関数内にあります。手動で書く必要はありません。しかし、原則はまったく同じです。

関連する問題