可以通过从同一
handle_continue
内的另一个回调返回 GenServer
来调用 {:noreply, state, {:continue, :foo}
的 GenServer
回调。
如果我在
GenServer.init
回调之后有一小部分单独的步骤:
defmodule MyGenServer do
use GenServer
def start_link(args \\ %{}) do
GenServer.start_link(__MODULE__, args, [])
end
@impl true
def init(args) do
{:ok, args, {:continue, :foo}}
end
@impl true
def handle_continue(:foo, state)
case foo(state) do
{:ok, state} ->
{:noreply, state, {:continue, :bar}}
{:error, :bar_not_set} ->
{:noreply, state}
end
@impl true
def handle_continue(:bar, state)
state = bar(state)
{:noreply, state}
end
defp foo(state = %{bar: _}) do
{:ok, state}
end
defp foo(_state) do
{:error, :bar_not_set}
end
defp bar(state) do
# ...
state
end
end
如果 handle_continue(:foo, state)
包含
handle_continue(:bar, state)
键,则按此顺序调用
args
和
bar
回调。如果不是,则永远不会调用
handle_continue(:bar, state)
回调。如果我已经开始
MyGenServer
例如作为监督树的一部分:
...
children = [
...
{MyGenServer, %{foo: "foo"}},
...
]
Supervisor.start_link(children, ...)
是否可以从监督树中的另一个进程触发MyGenServer.handle_continue(:bar, state)
回调?这更多的是一个问题,关于是否可以以任何其他方式调用
handle_continue
回调,而不是在同一个
GenServer
内进行回调之后,根本不可能,并且找不到执行
handle_continue(:bar, state)
中代码的替代方法。
def handle_cast(:invoke_the_continue, state) do
handle_continue(:bar, state)
end
然后从服务器外部调用 GenServer.cast(your_server, :invoke_the_continue)
。