目前我們要產生以及呼叫 GenServer 都是使用 GenServer.start_link/2
與 GenServer.call/3
等 GenServer 模組內的函式,但大部分的時候並不會直接使用,而是會將他們寫進去 use GenServer
的模組裡面 (當然還是視情況調整)
我們可以把目前寫的 Bank
模組補上呼叫時的函式,這個模組就有兩類函式,一區是 Client 使用的 API,另一邊是 Server 端的 GenServer callback 或是其他關聯函式。
defmodule Bank do
use GenServer
# Client functions
def start_link(init_balance) do
GenServer.start_link(__MODULE__, init_balance)
end
def add(pid, amount) do
GenServer.cast(pid, {:add, amount})
end
def check_balance(pid) do
GenServer.call(pid, :check_balance)
end
# Server callback functions
def init(init_balance) do
IO.puts("開戶存了 #{init_balance} 元。")
{:ok, init_balance}
end
def handle_cast({:add, amount}, balance) do
new_state = balance + amount
IO.puts("存入 #{amount} 元。")
{:noreply, new_state}
end
def handle_call(:check_balance, _from, balance) do
IO.puts("檢查餘額,目前有 #{balance} 元")
{:reply, balance, balance}
end
end
呼叫的時候就可以直接使用 Client 端的函式
iex(2)> {:ok, pid} = Bank.start_link(200)
開戶存了 200 元。
{:ok, #PID<0.114.0>}
iex(3)> Bank.add(pid, 400)
存入 400 元。
:ok
iex(4)> Bank.check_balance(pid)
檢查餘額,目前有 600 元
600